mcp-scraper 0.17.0 → 0.18.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/human-cli.ts","../../src/version.ts","../../src/cli/agent-config.ts","../../src/cli/doctor.ts","../../src/cli/prompts.ts","../../src/workflows/artifact-writer.ts","../../src/directory/csv.ts","../../src/lib/slugify.ts","../../src/output/memory-library-sink.ts","../../src/workflows/registry.ts","../../src/workflows/http-client.ts","../../src/workflows/workflows/agent-packet.ts","../../src/workflows/report-renderer.ts","../../src/workflows/workflows/directory.ts","../../src/schemas.ts","../../src/workflows/workflows/get-leads.ts","../../src/workflows/workflows/local-competitive-audit.ts","../../src/workflows/workflows/comparison-briefs.ts","../../src/workflows/workflows/seo-workflow-utils.ts","../../bin/mcp-scraper-cli.ts"],"sourcesContent":["import { Command } from 'commander'\nimport { spawn } from 'node:child_process'\nimport { mkdir, writeFile } from 'node:fs/promises'\nimport { basename, join } from 'node:path'\nimport { PACKAGE_VERSION } from '../version.js'\nimport {\n claudeMcpAddArgs,\n claudeMcpRemoveArgs,\n normalizeAgentHost,\n renderAgentInstall,\n type AgentHost,\n} from './agent-config.js'\nimport { renderDoctor, runDoctor } from './doctor.js'\nimport { listPrompts, renderPrompt } from './prompts.js'\nimport { workflowOutputBaseDir } from '../workflows/artifact-writer.js'\nimport { findWorkflowReport, listWorkflowDefinitions, listWorkflowReports, openWorkflowReport, runWorkflow } from '../workflows/registry.js'\n\nfunction numberOpt(value: unknown): number | undefined {\n if (value === undefined || value === null || value === '') return undefined\n const parsed = Number(value)\n return Number.isFinite(parsed) ? parsed : undefined\n}\n\nfunction booleanOpt(value: unknown): boolean | undefined {\n if (value === undefined) return undefined\n if (typeof value === 'boolean') return value\n if (value === 'true') return true\n if (value === 'false') return false\n return undefined\n}\n\nfunction compactInput(input: Record<string, unknown>): Record<string, unknown> {\n return Object.fromEntries(Object.entries(input).filter(([, value]) => value !== undefined))\n}\n\nfunction workflowInput(id: string, opts: Record<string, unknown>): Record<string, unknown> {\n if (id === 'agent-packet' || id === 'serp-comparison' || id === 'ai-overview-language') {\n return compactInput({\n keyword: opts.keyword,\n domain: opts.domain,\n url: opts.url,\n location: opts.location,\n maxResults: numberOpt(opts.maxResults),\n maxQuestions: numberOpt(opts.maxQuestions),\n extractTop: numberOpt(opts.extractTop),\n includeSerp: opts.serp === false ? false : undefined,\n includePaa: opts.paa === false ? false : undefined,\n includeAiOverview: booleanOpt(opts.includeAiOverview),\n returnPartial: opts.returnPartial === false ? false : undefined,\n })\n }\n\n if (id === 'paa-expansion-brief') {\n return compactInput({\n keyword: opts.keyword,\n location: opts.location,\n maxQuestions: numberOpt(opts.maxQuestions),\n depth: numberOpt(opts.depth),\n returnPartial: opts.returnPartial === false ? false : undefined,\n })\n }\n\n if (id === 'directory' || id === 'local-competitive-audit' || id === 'map-comparison') {\n return compactInput({\n query: opts.query,\n location: opts.location,\n state: opts.state,\n minPopulation: numberOpt(opts.minPop ?? opts.minPopulation),\n maxCities: numberOpt(opts.maxCities),\n maxResultsPerCity: numberOpt(opts.perCity ?? opts.maxResultsPerCity ?? opts.maxResults),\n concurrency: numberOpt(opts.concurrency),\n proxyMode: opts.proxyMode,\n hydrateTop: id === 'local-competitive-audit' || id === 'map-comparison' ? numberOpt(opts.hydrateTop) : undefined,\n maxReviews: id === 'local-competitive-audit' || id === 'map-comparison' ? numberOpt(opts.reviews ?? opts.maxReviews) : undefined,\n returnPartial: opts.returnPartial === false ? false : undefined,\n })\n }\n\n return compactInput(opts)\n}\n\nfunction writeOutput(data: unknown, json: boolean | undefined): void {\n if (json) {\n process.stdout.write(`${JSON.stringify(data, null, 2)}\\n`)\n } else if (typeof data === 'string') {\n process.stdout.write(`${data}\\n`)\n } else {\n process.stdout.write(`${JSON.stringify(data, null, 2)}\\n`)\n }\n}\n\nfunction maskSecrets(value: string): string {\n return value.replace(/sk_[A-Za-z0-9_-]+/g, 'sk_***')\n}\n\nfunction runLocalCommand(command: string, args: string[]): Promise<{ code: number; stdout: string; stderr: string }> {\n return new Promise((resolve) => {\n const child = spawn(command, args, { stdio: ['ignore', 'pipe', 'pipe'] })\n const stdout: Buffer[] = []\n const stderr: Buffer[] = []\n let settled = false\n const done = (result: { code: number; stdout: string; stderr: string }) => {\n if (settled) return\n settled = true\n resolve(result)\n }\n child.stdout.on('data', chunk => stdout.push(Buffer.from(chunk)))\n child.stderr.on('data', chunk => stderr.push(Buffer.from(chunk)))\n child.on('error', err => {\n done({ code: 127, stdout: '', stderr: err.message })\n })\n child.on('close', code => {\n done({\n code: typeof code === 'number' ? code : 1,\n stdout: Buffer.concat(stdout).toString('utf8'),\n stderr: Buffer.concat(stderr).toString('utf8'),\n })\n })\n })\n}\n\nfunction cadenceOpt(opts: Record<string, unknown>): 'daily' | 'weekly' | 'monthly' {\n if (opts.daily) return 'daily'\n if (opts.monthly) return 'monthly'\n return 'weekly'\n}\n\nfunction apiOptions(opts: Record<string, unknown>): { apiUrl: string; apiKey: string } {\n const apiKey = String(opts.apiKey ?? process.env.MCP_SCRAPER_API_KEY ?? '').trim()\n if (!apiKey) throw new Error('MCP_SCRAPER_API_KEY is required. Pass --api-key or set the environment variable.')\n return {\n apiUrl: String(opts.apiUrl ?? process.env.MCP_SCRAPER_API_URL ?? 'https://mcpscraper.dev').replace(/\\/$/, ''),\n apiKey,\n }\n}\n\nfunction openExternalUrl(url: string): boolean {\n const command = process.platform === 'darwin'\n ? 'open'\n : process.platform === 'win32'\n ? 'cmd'\n : 'xdg-open'\n const args = process.platform === 'win32' ? ['/c', 'start', '', url] : [url]\n try {\n const child = spawn(command, args, { detached: true, stdio: 'ignore' })\n child.unref()\n return true\n } catch {\n return false\n }\n}\n\nasync function apiRequest<T>(path: string, method: string, opts: Record<string, unknown>, body?: unknown): Promise<T> {\n const { apiUrl, apiKey } = apiOptions(opts)\n const res = await fetch(`${apiUrl}${path}`, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: body == null ? undefined : JSON.stringify(body),\n })\n const data = await res.json().catch(() => ({}))\n if (!res.ok) {\n const message = typeof (data as { error?: unknown }).error === 'string'\n ? (data as { error: string }).error\n : `API request failed with ${res.status}`\n throw new Error(message)\n }\n return data as T\n}\n\nfunction addWorkflowInputOptions(command: Command): Command {\n return command\n .option('--keyword <keyword>', 'Agent packet keyword')\n .option('--domain <domain>', 'Target domain')\n .option('--url <url>', 'Target page URL')\n .option('--location <location>', 'Target location')\n .option('--max-results <n>', 'Maximum SERP or Maps results')\n .option('--max-questions <n>', 'Maximum PAA questions')\n .option('--extract-top <n>', 'Top result pages or citation pages to extract')\n .option('--depth <n>', 'PAA expansion depth')\n .option('--no-serp', 'Skip SERP evidence for agent packet')\n .option('--no-paa', 'Skip PAA evidence for agent packet')\n .option('--query <query>', 'Business category or workflow query')\n .option('--state <state>', 'US state')\n .option('--min-pop <n>', 'Minimum city population')\n .option('--max-cities <n>', 'Maximum selected cities')\n .option('--per-city <n>', 'Maps results per city')\n .option('--concurrency <n>', 'City search concurrency')\n .option('--proxy-mode <mode>', 'Proxy mode: location, configured, or none')\n .option('--hydrate-top <n>', 'Profiles to hydrate per city for competitive audits')\n .option('--reviews <n>', 'Review cards to collect per hydrated profile')\n .option('--no-return-partial', 'Fail instead of writing partial artifacts')\n}\n\nexport function buildHumanCli(): Command {\n const program = new Command()\n program\n .name('mcp-scraper-cli')\n .description('Human CLI for MCP Scraper setup, workflows, reports, and agent-ready SEO artifacts.')\n .version(PACKAGE_VERSION)\n\n program.command('doctor')\n .description('Check setup, API key, output directory, package version, and recommended MCP config.')\n .option('--api-key <key>', 'MCP Scraper API key')\n .option('--api-url <url>', 'MCP Scraper API URL', 'https://mcpscraper.dev')\n .option('--output-dir <path>', 'Output directory to test')\n .option('--json', 'Print machine-readable JSON')\n .action(async (opts) => {\n const output = await runDoctor({ apiKey: opts.apiKey, apiUrl: opts.apiUrl, outputDir: opts.outputDir })\n writeOutput(opts.json ? output : renderDoctor(output), opts.json)\n if (!output.ok) process.exitCode = 1\n })\n\n const billing = program.command('billing').description('Inspect billing and start checkout flows.')\n const billingConcurrency = billing.command('concurrency').description('Manage MCP Scraper concurrency slots.')\n\n billingConcurrency.command('info')\n .description('Show current concurrency limit and extra-slot price.')\n .option('--api-key <key>', 'MCP Scraper API key')\n .option('--api-url <url>', 'MCP Scraper API URL', 'https://mcpscraper.dev')\n .option('--json', 'Print machine-readable JSON')\n .action(async (opts) => {\n const result = await apiRequest<{ concurrency: Record<string, unknown> }>('/billing/credits', 'POST', opts, {})\n if (opts.json) writeOutput(result.concurrency, true)\n else {\n const upgrade = result.concurrency?.upgrade as Record<string, unknown> | undefined\n writeOutput([\n `Current limit: ${result.concurrency?.current_limit ?? 'unknown'} concurrent operations`,\n `Extra slots: ${result.concurrency?.current_extra_slots ?? 'unknown'}`,\n `Extra concurrency slot: ${upgrade?.price_label ?? '$5/month'}`,\n `Upgrade command: ${upgrade?.terminal_command ?? 'mcp-scraper-cli billing concurrency checkout'}`,\n ].join('\\n'), false)\n }\n })\n\n billingConcurrency.command('checkout')\n .description('Create a hosted Stripe checkout for one extra concurrency slot.')\n .option('--api-key <key>', 'MCP Scraper API key')\n .option('--api-url <url>', 'MCP Scraper API URL', 'https://mcpscraper.dev')\n .option('--json', 'Print machine-readable JSON')\n .option('--no-open', 'Print the checkout URL without opening a browser')\n .action(async (opts) => {\n const result = await apiRequest<{ checkout_url: string; price?: { price_label?: string }; next_step?: string }>('/billing/concurrency/terminal-checkout', 'POST', opts, {})\n if (opts.json) {\n writeOutput(result, true)\n return\n }\n const opened = opts.open !== false && openExternalUrl(result.checkout_url)\n writeOutput([\n `Extra concurrency slot: ${result.price?.price_label ?? '$5/month'}`,\n opened ? `Opened checkout: ${result.checkout_url}` : `Checkout URL: ${result.checkout_url}`,\n result.next_step ?? 'Complete checkout, then retry the MCP request.',\n ].join('\\n'), false)\n })\n\n billing.command('subscribe <tier>')\n .description('Subscribe to a plan (starter | growth | scale) via a hosted Stripe checkout link.')\n .option('--api-key <key>', 'MCP Scraper API key')\n .option('--api-url <url>', 'MCP Scraper API URL', 'https://mcpscraper.dev')\n .option('--json', 'Print machine-readable JSON')\n .option('--no-open', 'Print the checkout URL without opening a browser')\n .action(async (tier, opts) => {\n const result = await apiRequest<{ checkout_url?: string; updated?: boolean; tier?: string; label?: string; monthly_usd?: number; credits_per_month?: number; concurrency?: number; intro?: string | null; message?: string; next_step?: string }>('/billing/subscribe/terminal-checkout', 'POST', opts, { tier: String(tier).toLowerCase() })\n if (opts.json) { writeOutput(result, true); return }\n if (result.updated) { writeOutput(result.message ?? `Switched to ${result.tier}.`, false); return }\n const opened = opts.open !== false && !!result.checkout_url && openExternalUrl(result.checkout_url)\n writeOutput([\n `Plan: ${result.label ?? tier} — $${result.monthly_usd}/mo · ${result.credits_per_month?.toLocaleString()} credits/mo · ${result.concurrency} concurrency${result.intro ? ` · ${result.intro}` : ''}`,\n opened ? `Opened checkout: ${result.checkout_url}` : `Checkout URL: ${result.checkout_url}`,\n result.next_step ?? 'Complete payment in the browser.',\n ].join('\\n'), false)\n })\n\n const agent = program.command('agent').description('Generate AI-agent install configs and workflow prompts.')\n agent.command('install <host>')\n .description('Print or apply install/config instructions for codex, claude/claude-code, or claude-desktop.')\n .option('--api-key <key>', 'API key to place in generated config')\n .option('--package <spec>', 'npm package spec', 'mcp-scraper@latest')\n .option('--browser-profile <name>', 'Default saved browser profile for browser_open sessions.')\n .option('--save-browser-profile-changes', 'Persist cookies and browser storage back to the named browser profile when sessions close')\n .option('--apply', 'Apply the config to this client when supported. For Claude Code, this upserts the user-scope mcp-scraper server.')\n .option('--json', 'Print machine-readable JSON')\n .action(async (hostInput: AgentHost, opts) => {\n const host = normalizeAgentHost(hostInput)\n const apiKey = opts.apiKey ?? process.env.MCP_SCRAPER_API_KEY\n if (opts.apply) {\n if (host !== 'claude') throw new Error('--apply is currently supported for Claude Code only. Use host \"claude\" or \"claude-code\".')\n if (!apiKey?.trim()) {\n throw new Error('MCP_SCRAPER_API_KEY is required for --apply. Set it in the environment or pass --api-key.')\n }\n\n const configOptions = {\n apiKey,\n packageSpec: opts.package,\n browserProfileName: opts.browserProfile,\n browserProfileSaveChanges: opts.saveBrowserProfileChanges,\n }\n const remove = await runLocalCommand('claude', claudeMcpRemoveArgs())\n const add = await runLocalCommand('claude', claudeMcpAddArgs(configOptions))\n if (add.code !== 0) {\n const reason = maskSecrets([add.stderr, add.stdout].filter(Boolean).join('\\n').trim())\n throw new Error([\n 'Claude Code MCP registration failed.',\n reason || 'No error output returned.',\n 'Make sure Claude Code is installed and the `claude` command is on PATH.',\n ].join('\\n'))\n }\n const list = await runLocalCommand('claude', ['mcp', 'list'])\n const result = {\n host: 'claude',\n applied: true,\n replacedExisting: remove.code === 0,\n command: 'npx',\n args: ['-y', '-p', opts.package, 'mcp-scraper'],\n nextStep: 'Fully exit Claude Code, start a new Claude terminal, then run: claude mcp list',\n list: maskSecrets([list.stdout, list.stderr].filter(Boolean).join('\\n').trim()),\n }\n if (opts.json) {\n writeOutput(result, true)\n return\n }\n writeOutput([\n 'Applied Claude Code MCP config: mcp-scraper',\n remove.code === 0 ? 'Replaced existing mcp-scraper entry.' : 'No existing mcp-scraper entry found; added a new one.',\n 'Command: npx -y -p ' + opts.package + ' mcp-scraper',\n opts.browserProfile ? `Browser profile: ${opts.browserProfile}` : '',\n '',\n 'Next step: fully exit Claude Code, start a new Claude terminal, then run:',\n ' claude mcp list',\n '',\n result.list ? `Current Claude MCP list:\\n${result.list}` : '',\n ].filter(Boolean).join('\\n'), false)\n return\n }\n const text = renderAgentInstall(host, {\n apiKey: opts.apiKey,\n packageSpec: opts.package,\n browserProfileName: opts.browserProfile,\n browserProfileSaveChanges: opts.saveBrowserProfileChanges,\n })\n writeOutput(opts.json ? { host, text } : text, opts.json)\n })\n\n agent.command('prompt [name]')\n .description('Print an agent prompt template.')\n .option('--json', 'Print machine-readable JSON')\n .action((name: string | undefined, opts) => {\n if (!name) {\n writeOutput(opts.json ? { prompts: listPrompts() } : listPrompts().join('\\n'), opts.json)\n return\n }\n const text = renderPrompt(name)\n writeOutput(opts.json ? { name, text } : text, opts.json)\n })\n\n const workflow = program.command('workflow').description('Run named SEO workflows.')\n workflow.command('list')\n .description('List available workflows.')\n .option('--json', 'Print machine-readable JSON')\n .action((opts) => {\n const rows = listWorkflowDefinitions()\n if (opts.json) writeOutput({ workflows: rows }, true)\n else writeOutput(rows.map(row => `${row.id}\\t${row.title}\\n ${row.description}`).join('\\n'), false)\n })\n\n workflow.command('run <id>')\n .description('Run a workflow and save local artifacts.')\n .option('--api-key <key>', 'MCP Scraper API key')\n .option('--api-url <url>', 'MCP Scraper API URL', 'https://mcpscraper.dev')\n .option('--output-dir <path>', 'Workflow output directory')\n .option('--json', 'Print machine-readable JSON')\n .option('--keyword <keyword>', 'Agent packet keyword')\n .option('--domain <domain>', 'Target domain')\n .option('--url <url>', 'Target page URL')\n .option('--location <location>', 'Target location')\n .option('--max-results <n>', 'Maximum SERP or Maps results')\n .option('--max-questions <n>', 'Maximum PAA questions')\n .option('--extract-top <n>', 'Top result pages or citation pages to extract')\n .option('--depth <n>', 'PAA expansion depth')\n .option('--no-serp', 'Skip SERP evidence for agent packet')\n .option('--no-paa', 'Skip PAA evidence for agent packet')\n .option('--query <query>', 'Business category or workflow query')\n .option('--state <state>', 'US state')\n .option('--min-pop <n>', 'Minimum city population')\n .option('--max-cities <n>', 'Maximum selected cities')\n .option('--per-city <n>', 'Maps results per city')\n .option('--concurrency <n>', 'City search concurrency')\n .option('--proxy-mode <mode>', 'Proxy mode: location, configured, or none')\n .option('--hydrate-top <n>', 'Profiles to hydrate per city for competitive audits')\n .option('--reviews <n>', 'Review cards to collect per hydrated profile')\n .option('--no-return-partial', 'Fail instead of writing partial artifacts')\n .action(async (id: string, opts) => {\n const summary = await runWorkflow(id, workflowInput(id, opts), {\n apiKey: opts.apiKey,\n apiUrl: opts.apiUrl,\n outputDir: opts.outputDir,\n })\n if (opts.json) writeOutput(summary, true)\n else {\n writeOutput([\n `${summary.title}: ${summary.status}`,\n summary.summary,\n summary.reportPath ? `Report: ${summary.reportPath}` : '',\n summary.warnings.length ? `Warnings:\\n${summary.warnings.map(w => `- ${w}`).join('\\n')}` : '',\n ].filter(Boolean).join('\\n'), false)\n }\n })\n\n const report = program.command('report').description('List and open local workflow reports.')\n report.command('list')\n .description('List recent workflow reports.')\n .option('--output-dir <path>', 'Workflow output directory')\n .option('--json', 'Print machine-readable JSON')\n .action(async (opts) => {\n const reports = await listWorkflowReports(opts.outputDir)\n writeOutput(opts.json ? { reports } : reports.map(r => `${r.startedAt}\\t${r.workflow}\\t${r.status}\\t${r.reportPath ?? r.manifestPath}`).join('\\n'), opts.json)\n })\n report.command('path [id]')\n .description('Print a report path. Defaults to last.')\n .option('--output-dir <path>', 'Workflow output directory')\n .option('--json', 'Print machine-readable JSON')\n .action(async (id = 'last', opts) => {\n const found = await findWorkflowReport(id, opts.outputDir)\n if (!found?.reportPath) throw new Error(`No report found for \"${id}\"`)\n writeOutput(opts.json ? { path: found.reportPath, run: found } : found.reportPath, opts.json)\n })\n report.command('open [id]')\n .description('Open a report. Defaults to last.')\n .option('--output-dir <path>', 'Workflow output directory')\n .option('--json', 'Print machine-readable JSON instead of opening')\n .action(async (id = 'last', opts) => {\n if (opts.json) {\n const found = await findWorkflowReport(id, opts.outputDir)\n if (!found?.reportPath) throw new Error(`No report found for \"${id}\"`)\n writeOutput({ path: found.reportPath, run: found }, true)\n return\n }\n const path = await openWorkflowReport(id, opts.outputDir)\n writeOutput(`Opened: ${path}`, false)\n })\n\n const schedule = program.command('schedule').description('Create and manage hosted workflow schedules.')\n addWorkflowInputOptions(schedule.command('create <workflowId>')\n .description('Create a recurring hosted workflow schedule.')\n .option('--api-key <key>', 'MCP Scraper API key')\n .option('--api-url <url>', 'MCP Scraper API URL', 'https://mcpscraper.dev')\n .option('--name <name>', 'Schedule name')\n .option('--daily', 'Run daily')\n .option('--weekly', 'Run weekly')\n .option('--monthly', 'Run monthly')\n .option('--timezone <tz>', 'Schedule timezone', 'UTC')\n .option('--webhook <url>', 'HTTPS webhook URL')\n .option('--next-run-at <iso>', 'First run time as an ISO timestamp')\n .option('--json', 'Print machine-readable JSON'))\n .action(async (workflowId: string, opts) => {\n const result = await apiRequest('/workflows/schedules', 'POST', opts, {\n workflowId,\n name: opts.name,\n input: workflowInput(workflowId, opts),\n cadence: cadenceOpt(opts),\n timezone: opts.timezone,\n webhookUrl: opts.webhook,\n nextRunAt: opts.nextRunAt,\n })\n writeOutput(result, opts.json)\n })\n\n schedule.command('list')\n .description('List hosted workflow schedules.')\n .option('--api-key <key>', 'MCP Scraper API key')\n .option('--api-url <url>', 'MCP Scraper API URL', 'https://mcpscraper.dev')\n .option('--json', 'Print machine-readable JSON')\n .action(async (opts) => {\n const result = await apiRequest<{ schedules: Array<Record<string, unknown>> }>('/workflows/schedules', 'GET', opts)\n if (opts.json) writeOutput(result, true)\n else writeOutput(result.schedules.map(scheduleRow => `${scheduleRow.id}\\t${scheduleRow.status}\\t${scheduleRow.workflow_id}\\t${scheduleRow.next_run_at ?? ''}`).join('\\n'), false)\n })\n\n schedule.command('pause <id>')\n .description('Pause a hosted workflow schedule.')\n .option('--api-key <key>', 'MCP Scraper API key')\n .option('--api-url <url>', 'MCP Scraper API URL', 'https://mcpscraper.dev')\n .option('--json', 'Print machine-readable JSON')\n .action(async (id: string, opts) => writeOutput(await apiRequest(`/workflows/schedules/${id}`, 'PATCH', opts, { status: 'paused' }), opts.json))\n\n schedule.command('resume <id>')\n .description('Resume a hosted workflow schedule.')\n .option('--api-key <key>', 'MCP Scraper API key')\n .option('--api-url <url>', 'MCP Scraper API URL', 'https://mcpscraper.dev')\n .option('--json', 'Print machine-readable JSON')\n .action(async (id: string, opts) => writeOutput(await apiRequest(`/workflows/schedules/${id}`, 'PATCH', opts, { status: 'active' }), opts.json))\n\n schedule.command('delete <id>')\n .description('Delete a hosted workflow schedule.')\n .option('--api-key <key>', 'MCP Scraper API key')\n .option('--api-url <url>', 'MCP Scraper API URL', 'https://mcpscraper.dev')\n .option('--json', 'Print machine-readable JSON')\n .action(async (id: string, opts) => writeOutput(await apiRequest(`/workflows/schedules/${id}`, 'DELETE', opts), opts.json))\n\n schedule.command('run <id>')\n .description('Run a hosted workflow schedule now.')\n .option('--api-key <key>', 'MCP Scraper API key')\n .option('--api-url <url>', 'MCP Scraper API URL', 'https://mcpscraper.dev')\n .option('--json', 'Print machine-readable JSON')\n .action(async (id: string, opts) => writeOutput(await apiRequest(`/workflows/schedules/${id}/run`, 'POST', opts, {}), opts.json))\n\n const runs = program.command('runs').description('Inspect and download hosted workflow runs.')\n runs.command('list')\n .description('List hosted workflow runs.')\n .option('--api-key <key>', 'MCP Scraper API key')\n .option('--api-url <url>', 'MCP Scraper API URL', 'https://mcpscraper.dev')\n .option('--json', 'Print machine-readable JSON')\n .action(async (opts) => {\n const result = await apiRequest<{ runs: Array<Record<string, unknown>> }>('/workflows/runs', 'GET', opts)\n if (opts.json) writeOutput(result, true)\n else writeOutput(result.runs.map(run => `${run.id}\\t${run.status}\\t${run.workflow_id}\\t${run.queued_at}`).join('\\n'), false)\n })\n\n runs.command('status <id>')\n .description('Show a hosted workflow run.')\n .option('--api-key <key>', 'MCP Scraper API key')\n .option('--api-url <url>', 'MCP Scraper API URL', 'https://mcpscraper.dev')\n .option('--json', 'Print machine-readable JSON')\n .action(async (id: string, opts) => writeOutput(await apiRequest(`/workflows/runs/${id}`, 'GET', opts), opts.json))\n\n runs.command('download <id>')\n .description('Download hosted workflow run artifacts.')\n .option('--api-key <key>', 'MCP Scraper API key')\n .option('--api-url <url>', 'MCP Scraper API URL', 'https://mcpscraper.dev')\n .option('--output-dir <path>', 'Download directory')\n .option('--json', 'Print machine-readable JSON')\n .action(async (id: string, opts) => {\n const result = await apiRequest<{ run: { id: string; artifacts?: Array<{ id: string; label: string; path: string }> } }>(`/workflows/runs/${id}`, 'GET', opts)\n const { apiUrl, apiKey } = apiOptions(opts)\n const outDir = join(opts.outputDir ?? workflowOutputBaseDir(), 'workflow-downloads', id)\n await mkdir(outDir, { recursive: true })\n const downloaded: string[] = []\n for (const artifact of result.run.artifacts ?? []) {\n const res = await fetch(`${apiUrl}/workflows/runs/${id}/artifacts/${artifact.id}`, { headers: { 'x-api-key': apiKey } })\n if (!res.ok) throw new Error(`Failed to download ${artifact.label}: HTTP ${res.status}`)\n const file = join(outDir, basename(artifact.path))\n await writeFile(file, Buffer.from(await res.arrayBuffer()))\n downloaded.push(file)\n }\n writeOutput(opts.json ? { runId: id, files: downloaded } : downloaded.join('\\n'), opts.json)\n })\n\n return program\n}\n\nexport async function runHumanCli(argv = process.argv): Promise<void> {\n await buildHumanCli().parseAsync(argv)\n}\n","export const PACKAGE_VERSION = '0.17.0'\n","export type AgentHost = 'codex' | 'claude' | 'claude-code' | 'claude-desktop'\n\nexport interface AgentConfigOptions {\n apiKey?: string\n packageSpec?: string\n browserProfileName?: string\n browserProfileSaveChanges?: boolean\n}\n\nfunction apiKeyValue(options: AgentConfigOptions): string {\n return options.apiKey?.trim() || 'sk_live_your_key'\n}\n\nfunction packageSpec(options: AgentConfigOptions): string {\n return options.packageSpec?.trim() || 'mcp-scraper@latest'\n}\n\nexport function combinedNpxArgs(options: AgentConfigOptions = {}): string[] {\n return ['-y', '-p', packageSpec(options), 'mcp-scraper']\n}\n\nfunction envConfig(options: AgentConfigOptions): Record<string, string> {\n const env: Record<string, string> = { MCP_SCRAPER_API_KEY: apiKeyValue(options) }\n const profileName = options.browserProfileName?.trim()\n if (profileName) env.BROWSER_AGENT_PROFILE_NAME = profileName\n if (options.browserProfileSaveChanges === true) env.BROWSER_AGENT_PROFILE_SAVE_CHANGES = 'true'\n return env\n}\n\nfunction tomlInlineTable(value: Record<string, string>): string {\n const entries = Object.entries(value).map(([key, item]) => `${key} = ${JSON.stringify(item)}`)\n return `{ ${entries.join(', ')} }`\n}\n\nexport function renderCodexConfig(options: AgentConfigOptions = {}): string {\n return [\n '[mcp_servers.mcp-scraper]',\n 'command = \"npx\"',\n `args = ${JSON.stringify(combinedNpxArgs(options))}`,\n `env = ${tomlInlineTable(envConfig(options))}`,\n ].join('\\n')\n}\n\nexport function renderClaudeCommand(options: AgentConfigOptions = {}): string {\n const env = Object.entries(envConfig(options)).map(([key, value]) => ` --env ${key}=${value}`)\n return [\n 'claude mcp add mcp-scraper --scope user',\n ...env,\n ` -- npx ${combinedNpxArgs(options).join(' ')}`,\n ].join(' \\\\\\n')\n}\n\nexport function claudeMcpRemoveArgs(): string[] {\n return ['mcp', 'remove', 'mcp-scraper', '-s', 'user']\n}\n\nexport function claudeMcpAddArgs(options: AgentConfigOptions = {}): string[] {\n const args = ['mcp', 'add', 'mcp-scraper', '--scope', 'user']\n for (const [key, value] of Object.entries(envConfig(options))) {\n args.push('--env', `${key}=${value}`)\n }\n args.push('--', 'npx', ...combinedNpxArgs(options))\n return args\n}\n\nexport function normalizeAgentHost(host: string): AgentHost {\n if (host === 'claude-code') return 'claude'\n if (host === 'claude' || host === 'codex' || host === 'claude-desktop') return host\n throw new Error('Unknown host \"' + host + '\". Use: codex, claude, claude-code, or claude-desktop')\n}\n\nexport function renderClaudeDesktopConfig(options: AgentConfigOptions = {}): string {\n return JSON.stringify({\n mcpServers: {\n 'mcp-scraper': {\n command: 'npx',\n args: combinedNpxArgs(options),\n env: envConfig(options),\n },\n },\n }, null, 2)\n}\n\nexport function renderAgentInstall(host: AgentHost, options: AgentConfigOptions = {}): string {\n const normalizedHost = normalizeAgentHost(host)\n const restart = 'Restart the MCP client so it starts a fresh npx process.'\n const applyCommand = `MCP_SCRAPER_API_KEY=${apiKeyValue(options)} npx -y -p mcp-scraper@latest mcp-scraper-cli agent install claude --apply`\n if (normalizedHost === 'codex') {\n return [\n '# Codex MCP config',\n renderCodexConfig(options),\n '',\n restart,\n ].join('\\n')\n }\n if (normalizedHost === 'claude') {\n return [\n '# Claude Code command',\n renderClaudeCommand(options),\n '',\n '# One-command Claude Code setup',\n applyCommand,\n '',\n restart,\n ].join('\\n')\n }\n return [\n '# Claude Desktop config',\n renderClaudeDesktopConfig(options),\n '',\n 'Desktop Extension: https://mcpscraper.dev/downloads/mcp-scraper.mcpb',\n restart,\n ].join('\\n')\n}\n","import { access, mkdir, readFile } from 'node:fs/promises'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { PACKAGE_VERSION } from '../version.js'\nimport { combinedNpxArgs } from './agent-config.js'\n\nexport type DoctorStatus = 'pass' | 'warn' | 'fail' | 'skip'\n\nexport interface DoctorCheck {\n id: string\n label: string\n status: DoctorStatus\n detail: string\n fix?: string\n}\n\nexport interface DoctorOptions {\n apiKey?: string\n apiUrl?: string\n outputDir?: string\n fetchImpl?: typeof fetch\n}\n\nexport interface DoctorOutput {\n ok: boolean\n version: string\n npmLatest: string | null\n checks: DoctorCheck[]\n recommendedConfig: {\n command: 'npx'\n args: string[]\n env: Record<string, string>\n }\n}\n\nfunction status(ok: boolean, warn = false): DoctorStatus {\n if (ok) return 'pass'\n return warn ? 'warn' : 'fail'\n}\n\nfunction parseMajor(version: string): number {\n return Number(version.replace(/^v/, '').split('.')[0] ?? 0)\n}\n\nasync function readKeyFile(): Promise<string | null> {\n const path = process.env.MCP_SCRAPER_KEY_PATH?.trim() || join(homedir(), '.mcp-scraper-key')\n try {\n const value = (await readFile(path, 'utf8')).trim()\n return value || null\n } catch {\n return null\n }\n}\n\nasync function npmLatest(fetchImpl: typeof fetch): Promise<string | null> {\n try {\n const res = await fetchImpl('https://registry.npmjs.org/mcp-scraper/latest', {\n signal: AbortSignal.timeout(5_000),\n })\n if (!res.ok) return null\n const data = await res.json() as { version?: string }\n return data.version ?? null\n } catch {\n return null\n }\n}\n\nexport async function runDoctor(options: DoctorOptions = {}): Promise<DoctorOutput> {\n const fetchImpl = options.fetchImpl ?? fetch\n const apiUrl = (options.apiUrl ?? process.env.MCP_SCRAPER_API_URL ?? 'https://mcpscraper.dev').replace(/\\/$/, '')\n const outputDir = options.outputDir ?? process.env.MCP_SCRAPER_OUTPUT_DIR ?? join(homedir(), 'Downloads', 'mcp-scraper')\n const configuredKey = options.apiKey?.trim() || process.env.MCP_SCRAPER_API_KEY?.trim() || await readKeyFile()\n const latest = await npmLatest(fetchImpl)\n\n const checks: DoctorCheck[] = []\n const nodeMajor = parseMajor(process.version)\n checks.push({\n id: 'node',\n label: 'Node.js',\n status: status(nodeMajor >= 20),\n detail: process.version,\n fix: nodeMajor >= 20 ? undefined : 'Install Node.js 20 or newer.',\n })\n\n checks.push({\n id: 'package_version',\n label: 'Local package',\n status: latest && latest !== PACKAGE_VERSION ? 'warn' : 'pass',\n detail: latest ? `local ${PACKAGE_VERSION}, npm latest ${latest}` : `local ${PACKAGE_VERSION}, npm latest unavailable`,\n fix: latest && latest !== PACKAGE_VERSION ? 'Use mcp-scraper@latest and restart the MCP client.' : undefined,\n })\n\n checks.push({\n id: 'api_key',\n label: 'API key',\n status: configuredKey ? 'pass' : 'warn',\n detail: configuredKey ? 'configured' : 'not configured',\n fix: configuredKey ? undefined : 'Set MCP_SCRAPER_API_KEY or pass --api-key.',\n })\n\n try {\n await mkdir(outputDir, { recursive: true })\n await access(outputDir)\n checks.push({ id: 'output_dir', label: 'Output directory', status: 'pass', detail: outputDir })\n } catch (err) {\n checks.push({\n id: 'output_dir',\n label: 'Output directory',\n status: 'fail',\n detail: outputDir,\n fix: err instanceof Error ? err.message : 'Create a writable output directory.',\n })\n }\n\n if (configuredKey) {\n try {\n const res = await fetchImpl(`${apiUrl}/me`, {\n headers: { 'x-api-key': configuredKey },\n signal: AbortSignal.timeout(8_000),\n })\n checks.push({\n id: 'api_reachability',\n label: 'Hosted API',\n status: res.ok ? 'pass' : 'fail',\n detail: `${apiUrl}/me returned ${res.status}`,\n fix: res.ok ? undefined : 'Verify the API key and account status.',\n })\n } catch (err) {\n checks.push({\n id: 'api_reachability',\n label: 'Hosted API',\n status: 'fail',\n detail: err instanceof Error ? err.message : String(err),\n fix: 'Check network access and MCP_SCRAPER_API_URL.',\n })\n }\n } else {\n checks.push({\n id: 'api_reachability',\n label: 'Hosted API',\n status: 'skip',\n detail: 'skipped because no API key is configured',\n })\n }\n\n checks.push({\n id: 'mcp_config',\n label: 'MCP command',\n status: 'pass',\n detail: `npx ${combinedNpxArgs().join(' ')}`,\n fix: 'Restart the MCP client after package updates.',\n })\n\n return {\n ok: checks.every(check => check.status === 'pass' || check.status === 'skip'),\n version: PACKAGE_VERSION,\n npmLatest: latest,\n checks,\n recommendedConfig: {\n command: 'npx',\n args: combinedNpxArgs(),\n env: { MCP_SCRAPER_API_KEY: configuredKey ? '$MCP_SCRAPER_API_KEY' : 'sk_live_your_key' },\n },\n }\n}\n\nexport function renderDoctor(output: DoctorOutput): string {\n const icon: Record<DoctorStatus, string> = { pass: 'PASS', warn: 'WARN', fail: 'FAIL', skip: 'SKIP' }\n const lines = [\n `mcp-scraper doctor v${output.version}`,\n '',\n ...output.checks.map(check => {\n const fix = check.fix ? `\\n Fix: ${check.fix}` : ''\n return `[${icon[check.status]}] ${check.label}: ${check.detail}${fix}`\n }),\n '',\n `Recommended MCP command: npx ${output.recommendedConfig.args.join(' ')}`,\n ]\n return lines.join('\\n')\n}\n\n","export const AGENT_PROMPTS: Record<string, string> = {\n 'agent-packet': [\n '# MCP Scraper Agent Packet Prompt',\n '',\n 'Use MCP Scraper as the evidence layer. Run the agent-packet workflow for the target keyword/domain, then treat `evidence.json`, `sources.csv`, and `competitors.csv` as source of truth.',\n '',\n 'Do not invent citations. If a recommendation is not supported by the packet, mark it as an assumption. Turn the evidence into a concise SEO brief, an implementation task list, and content recommendations tied to source rows.',\n ].join('\\n'),\n 'local-competitive-audit': [\n '# MCP Scraper Local Competitive Audit Prompt',\n '',\n 'Run the local-competitive-audit workflow for the niche and markets. Use the city summary, competitor CSV, and review-insight CSV to identify market difficulty, review themes, GBP category patterns, and weak competitors.',\n '',\n 'Ground recommendations in Maps rank position, review count, star rating, categories, profile details, and review topics. Do not overstate heuristic opportunity scores.',\n ].join('\\n'),\n 'directory-workflow': [\n '# MCP Scraper Directory Workflow Prompt',\n '',\n 'Use directory_workflow when the user wants cities selected by population and Google Maps candidates per city. Keep query and location separate. Preserve result_position, source_location, review stars/count, categories, and profile URLs for downstream CSV or directory use.',\n ].join('\\n'),\n 'map-comparison': [\n '# MCP Scraper Maps Comparison Prompt',\n '',\n 'Run the map-comparison workflow when the user wants to compare local Maps competitors in a city or across selected markets. Use `maps-results.csv`, `map-comparison.csv`, and `profile-insights.csv` as source of truth.',\n '',\n 'Ground recommendations in result_position, review_stars, review_count, category, website presence, review topics, and profile attributes. Treat review gaps and missing websites as opportunity signals, not guaranteed ranking factors.',\n ].join('\\n'),\n 'serp-comparison': [\n '# MCP Scraper SERP Comparison Prompt',\n '',\n 'Run the serp-comparison workflow when the user wants to know why competitors outrank a page or what the SERP rewards. Use organic results, extracted page headings, PAA questions, and AI Overview citations before making recommendations.',\n '',\n 'Tie each recommendation to `content-gaps.csv`, `page-comparison.csv`, `paa-questions.csv`, or `ai-overview-citations.csv`. Do not invent missing sections or citations.',\n ].join('\\n'),\n 'paa-expansion-brief': [\n '# MCP Scraper PAA Expansion Brief Prompt',\n '',\n 'Run the paa-expansion-brief workflow when the user wants to figure out what to write from People Also Ask expansion. Use `section-map.csv` to structure the brief and `paa-questions.csv` for exact customer-language headings.',\n '',\n 'Answer the highest-priority questions directly, preserve source URLs when present, and separate evidence-backed sections from assumptions.',\n ].join('\\n'),\n 'ai-overview-language': [\n '# MCP Scraper AI Overview Language Prompt',\n '',\n 'Run the ai-overview-language workflow when the user wants to know how to phrase content for AI Overview inclusion. Use `claim-patterns.csv`, `language-guidance.csv`, `ai-overview-citations.csv`, and PAA follow-ups as evidence.',\n '',\n 'Recommend concise answer blocks, criteria/step language, citation hooks, and follow-up sections. Do not claim the target will be cited; frame the output as evidence-based language guidance.',\n ].join('\\n'),\n 'ai-citation-monitor': [\n '# MCP Scraper AI Citation Monitor Prompt',\n '',\n 'Use search_serp and harvest_paa to check whether the target brand/domain appears in AI Overview citations, organic results, People Also Ask sources, local pack, forums, and videos. Save evidence before summarizing trends or gaps.',\n ].join('\\n'),\n 'serp-brief': [\n '# MCP Scraper SERP Brief Prompt',\n '',\n 'Use live SERP, PAA, AI Overview, forum, video, and source evidence to create a writer brief. Tie each recommended section to evidence rows and identify missing proof, entities, comparisons, and customer questions.',\n ].join('\\n'),\n}\n\nexport function listPrompts(): string[] {\n return Object.keys(AGENT_PROMPTS).sort()\n}\n\nexport function renderPrompt(name: string): string {\n const prompt = AGENT_PROMPTS[name]\n if (!prompt) throw new Error(`Unknown prompt \"${name}\". Available: ${listPrompts().join(', ')}`)\n return prompt\n}\n","import { mkdir, readFile, stat, writeFile } from 'node:fs/promises'\nimport { existsSync } from 'node:fs'\nimport { homedir, platform } from 'node:os'\nimport { dirname, join } from 'node:path'\nimport { execFile } from 'node:child_process'\nimport { rowsToCsv } from '../directory/csv.js'\nimport { slugify } from '../lib/slugify.js'\nimport type { WorkflowArtifact, WorkflowManifest, WorkflowStatus } from './types.js'\nimport { postToMemoryLibrary } from '../output/memory-library-sink.js'\n\nexport function workflowOutputBaseDir(outputDir?: string): string {\n return outputDir?.trim() || process.env.MCP_SCRAPER_OUTPUT_DIR?.trim() || join(homedir(), 'Downloads', 'mcp-scraper')\n}\n\nfunction timestamp(): string {\n return new Date().toISOString().replace(/[:.]/g, '-')\n}\n\nfunction safeSlug(value: string): string {\n return slugify(value).replace(/^-+|-+$/g, '').slice(0, 80) || 'run'\n}\n\nexport class ArtifactWriter {\n readonly artifacts: WorkflowArtifact[] = []\n\n constructor(\n readonly workflowId: string,\n readonly title: string,\n readonly runId: string,\n readonly baseDir: string,\n readonly runDir: string,\n readonly startedAt: string,\n readonly input: Record<string, unknown>,\n ) {}\n\n static async create(workflowId: string, title: string, input: Record<string, unknown>, outputDir?: string, forcedRunId?: string): Promise<ArtifactWriter> {\n const startedAt = new Date().toISOString()\n const runId = forcedRunId?.trim() || `${timestamp()}-${safeSlug(workflowId)}-${Math.random().toString(36).slice(2, 8)}`\n const nameSource = String(input.keyword ?? input.query ?? input.domain ?? input.state ?? workflowId)\n const baseDir = workflowOutputBaseDir(outputDir)\n const runDir = join(baseDir, 'workflows', workflowId, `${timestamp()}-${safeSlug(nameSource)}-${safeSlug(runId).slice(0, 20)}`)\n await mkdir(runDir, { recursive: true })\n return new ArtifactWriter(workflowId, title, runId, baseDir, runDir, startedAt, input)\n }\n\n private async remember(kind: WorkflowArtifact['kind'], label: string, path: string, rows?: number): Promise<string> {\n const size = await stat(path).then(s => s.size).catch(() => undefined)\n this.artifacts.push({ kind, label, path, bytes: size, rows })\n await postToMemoryLibrary({ title: `${this.title} ${label}`, content: `artifact: ${path}`, source: `mcp-scraper-workflow:${this.workflowId}:${this.runId}` })\n return path\n }\n\n async writeJson(label: string, relativePath: string, data: unknown): Promise<string> {\n const path = join(this.runDir, relativePath)\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, JSON.stringify(data, null, 2), 'utf8')\n return this.remember('json', label, path)\n }\n\n async writeText(label: string, relativePath: string, text: string, kind: WorkflowArtifact['kind'] = 'markdown'): Promise<string> {\n const path = join(this.runDir, relativePath)\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, text, 'utf8')\n return this.remember(kind, label, path)\n }\n\n async writeCsv(label: string, relativePath: string, headers: string[], rows: Array<Record<string, unknown>>): Promise<string> {\n const path = join(this.runDir, relativePath)\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, rowsToCsv(headers, rows), 'utf8')\n return this.remember('csv', label, path, rows.length)\n }\n\n async writeHtml(label: string, relativePath: string, html: string): Promise<string> {\n return this.writeText(label, relativePath, html, 'html_report')\n }\n\n async writeManifest(status: WorkflowStatus, counts: Record<string, number>, warnings: string[], errors: string[]): Promise<string> {\n const manifest: WorkflowManifest = {\n workflow: this.workflowId,\n title: this.title,\n runId: this.runId,\n status,\n startedAt: this.startedAt,\n completedAt: status === 'running' ? null : new Date().toISOString(),\n input: this.input,\n artifacts: this.artifacts,\n warnings,\n errors,\n counts,\n }\n const path = join(this.runDir, 'manifest.json')\n await writeFile(path, JSON.stringify(manifest, null, 2), 'utf8')\n await updateWorkflowIndex(manifest, path, this.baseDir)\n return path\n }\n}\n\ninterface WorkflowIndexEntry {\n workflow: string\n runId: string\n status: string\n startedAt: string\n reportPath: string | null\n manifestPath: string\n summary: string\n}\n\ninterface WorkflowIndex {\n runs: WorkflowIndexEntry[]\n}\n\nfunction indexPath(baseDir = workflowOutputBaseDir()): string {\n return join(baseDir, 'workflows', 'index.json')\n}\n\nasync function readIndex(baseDir?: string): Promise<WorkflowIndex> {\n const path = indexPath(baseDir)\n if (!existsSync(path)) return { runs: [] }\n try {\n return JSON.parse(await readFile(path, 'utf8')) as WorkflowIndex\n } catch {\n return { runs: [] }\n }\n}\n\nasync function updateWorkflowIndex(manifest: WorkflowManifest, manifestPath: string, baseDir: string): Promise<void> {\n if (manifest.status === 'running') return\n const path = indexPath(baseDir)\n const index = await readIndex(baseDir)\n const report = manifest.artifacts.find(a => a.kind === 'html_report')?.path ?? null\n const entry: WorkflowIndexEntry = {\n workflow: manifest.workflow,\n runId: manifest.runId,\n status: manifest.status,\n startedAt: manifest.startedAt,\n reportPath: report,\n manifestPath,\n summary: `${manifest.title} (${manifest.status})`,\n }\n index.runs = [entry, ...index.runs.filter(r => r.runId !== manifest.runId)].slice(0, 200)\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, JSON.stringify(index, null, 2), 'utf8')\n}\n\nexport async function listWorkflowReports(outputDir?: string): Promise<WorkflowIndexEntry[]> {\n return (await readIndex(workflowOutputBaseDir(outputDir))).runs\n}\n\nexport async function findWorkflowReport(id: string, outputDir?: string): Promise<WorkflowIndexEntry | null> {\n const runs = await listWorkflowReports(outputDir)\n if (id === 'last') return runs[0] ?? null\n return runs.find(run => run.runId === id) ?? null\n}\n\nexport async function openWorkflowReport(id: string, outputDir?: string): Promise<string> {\n const run = await findWorkflowReport(id, outputDir)\n if (!run?.reportPath) throw new Error(`No report found for \"${id}\"`)\n if (platform() === 'darwin') {\n await new Promise<void>((resolve, reject) => {\n execFile('open', [run.reportPath!], (err) => err ? reject(err) : resolve())\n })\n }\n return run.reportPath\n}\n","export function parseCsv(text: string): string[][] {\n const rows: string[][] = []\n let row: string[] = []\n let field = ''\n let quoted = false\n\n for (let i = 0; i < text.length; i += 1) {\n const ch = text[i]\n const next = text[i + 1]\n\n if (quoted) {\n if (ch === '\"' && next === '\"') {\n field += '\"'\n i += 1\n } else if (ch === '\"') {\n quoted = false\n } else {\n field += ch\n }\n continue\n }\n\n if (ch === '\"') {\n quoted = true\n } else if (ch === ',') {\n row.push(field)\n field = ''\n } else if (ch === '\\n') {\n row.push(field)\n rows.push(row)\n row = []\n field = ''\n } else if (ch !== '\\r') {\n field += ch\n }\n }\n\n if (field.length > 0 || row.length > 0) {\n row.push(field)\n rows.push(row)\n }\n\n return rows\n}\n\nexport function csvRecords(text: string): Array<Record<string, string>> {\n const rows = parseCsv(text).filter(row => row.some(cell => cell.trim() !== ''))\n const header = rows[0]?.map(cell => cell.trim()) ?? []\n return rows.slice(1).map((row) => {\n const record: Record<string, string> = {}\n for (let i = 0; i < header.length; i += 1) {\n record[header[i]] = row[i] ?? ''\n }\n return record\n })\n}\n\nexport function csvCell(value: unknown): string {\n if (value === null || value === undefined) return ''\n const text = String(value)\n return /[\",\\n\\r]/.test(text) ? `\"${text.replace(/\"/g, '\"\"')}\"` : text\n}\n\nexport function rowsToCsv(headers: string[], rows: Array<Record<string, unknown>>): string {\n return [\n headers.join(','),\n ...rows.map(row => headers.map(header => csvCell(row[header])).join(',')),\n ].join('\\n') + '\\n'\n}\n","export function slugify(s: string): string {\n return s.toLowerCase().replace(/\\s+/g, '-').replace(/[^a-z0-9-]/g, '');\n}\n","export async function postToMemoryLibrary(args: { title: string; content: string; source: string }): Promise<void> {\n const url = process.env.MCP_MEMORY_INGEST_URL\n const key = process.env.MCP_MEMORY_KEY\n if (!url || !key) return\n try {\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ data: { apiKey: key, title: args.title, content: args.content, source: args.source } }),\n })\n const body = (await res.json().catch(() => null)) as { result?: { error?: boolean; message?: string } } | null\n if (!res.ok || body?.result?.error) {\n console.warn('[memory-library-sink] ingest not accepted:', res.status, body?.result?.message ?? '')\n }\n } catch (err) {\n console.warn('[memory-library-sink] ingest failed:', (err as Error)?.message)\n }\n}\n\nexport function memoryLibrarySinkEnabled(): boolean {\n return Boolean(process.env.MCP_MEMORY_INGEST_URL && process.env.MCP_MEMORY_KEY)\n}\n","import { readFile } from 'node:fs/promises'\nimport { z } from 'zod'\nimport { ArtifactWriter, findWorkflowReport, listWorkflowReports, openWorkflowReport } from './artifact-writer.js'\nimport { WorkflowHttpClient } from './http-client.js'\nimport type { WorkflowArtifact, WorkflowDefinition, WorkflowRunContext, WorkflowRunOptions, WorkflowRunSummary } from './types.js'\nimport { agentPacketWorkflowDefinition } from './workflows/agent-packet.js'\nimport { directoryWorkflowDefinition } from './workflows/directory.js'\nimport { getLeadsWorkflowDefinition } from './workflows/get-leads.js'\nimport { localCompetitiveAuditWorkflowDefinition } from './workflows/local-competitive-audit.js'\nimport {\n aiOverviewLanguageWorkflowDefinition,\n mapComparisonWorkflowDefinition,\n paaExpansionBriefWorkflowDefinition,\n serpComparisonWorkflowDefinition,\n} from './workflows/comparison-briefs.js'\n\nconst DEFINITIONS = [\n directoryWorkflowDefinition,\n getLeadsWorkflowDefinition,\n agentPacketWorkflowDefinition,\n localCompetitiveAuditWorkflowDefinition,\n mapComparisonWorkflowDefinition,\n serpComparisonWorkflowDefinition,\n paaExpansionBriefWorkflowDefinition,\n aiOverviewLanguageWorkflowDefinition,\n] satisfies WorkflowDefinition<any, any>[]\n\nexport interface WorkflowStepArtifact {\n kind: WorkflowArtifact['kind']\n label: string\n path: string\n bytes?: number\n rows?: number\n content: string\n}\n\nexport interface WorkflowStepRunResult {\n runId: string\n workflowId: string\n title: string\n stepIndex: number\n stepId: string\n stepTitle: string\n totalSteps: number\n isLast: boolean\n output: Record<string, unknown>\n state: unknown\n warnings: string[]\n summary: WorkflowRunSummary | null\n artifacts: WorkflowStepArtifact[]\n}\n\nexport function listWorkflowDefinitions(): Array<Pick<WorkflowDefinition, 'id' | 'title' | 'description'>> {\n return DEFINITIONS.map(({ id, title, description }) => ({ id, title, description }))\n}\n\nexport function workflowDefinition(id: string): WorkflowDefinition<any, any> {\n const definition = DEFINITIONS.find(def => def.id === id)\n if (!definition) throw new Error(`Unknown workflow \"${id}\". Available: ${DEFINITIONS.map(def => def.id).join(', ')}`)\n return definition\n}\n\nexport function workflowStepCount(id: string): number {\n const definition = workflowDefinition(id)\n return definition.steps?.length ?? 1\n}\n\nexport function workflowSupportsSteps(id: string): boolean {\n const definition = workflowDefinition(id)\n return Boolean(definition.steps && definition.steps.length > 0)\n}\n\nfunction resolveApiKey(options: WorkflowRunOptions): string {\n const apiKey = options.apiKey?.trim() || process.env.MCP_SCRAPER_API_KEY?.trim()\n if (!apiKey) throw new Error('MCP_SCRAPER_API_KEY is required for workflow runs. Pass --api-key or set the environment variable.')\n return apiKey\n}\n\nfunction resolveApiUrl(options: WorkflowRunOptions): string {\n return options.apiUrl?.trim() || process.env.MCP_SCRAPER_API_URL?.trim() || 'https://mcpscraper.dev'\n}\n\nexport async function runWorkflow(id: string, rawInput: Record<string, unknown>, options: WorkflowRunOptions = {}): Promise<WorkflowRunSummary> {\n const definition = workflowDefinition(id)\n const input = definition.inputSchema.parse(rawInput)\n const apiKey = resolveApiKey(options)\n const apiUrl = resolveApiUrl(options)\n const artifacts = await ArtifactWriter.create(definition.id, definition.title, input as Record<string, unknown>, options.outputDir, options.runId)\n const client = new WorkflowHttpClient(apiUrl, apiKey, options.fetchImpl, options.headers)\n const ctx: WorkflowRunContext = { runId: artifacts.runId, startedAt: artifacts.startedAt, client, artifacts, signal: options.signal }\n try {\n if (definition.steps && definition.steps.length > 0) {\n let state = definition.createState ? definition.createState(input) : ({} as unknown)\n let summary: WorkflowRunSummary | null = null\n for (const step of definition.steps) {\n const outcome = await step.run({ input, state, ctx })\n state = outcome.state\n if (outcome.summary) summary = outcome.summary\n }\n if (!summary) throw new Error(`Workflow \"${id}\" produced no terminal step summary`)\n return summary\n }\n if (definition.run) return await definition.run(input, ctx)\n throw new Error(`Workflow \"${id}\" has neither steps nor a run() implementation`)\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n await artifacts.writeText('Failure', 'summary.md', `# ${definition.title}\\n\\n${message}\\n`)\n await artifacts.writeManifest('failed', {}, [], [message])\n throw err\n }\n}\n\nexport async function runWorkflowStep(id: string, rawInput: Record<string, unknown>, opts: {\n stepIndex: number\n state?: unknown\n options?: WorkflowRunOptions\n}): Promise<WorkflowStepRunResult> {\n const definition = workflowDefinition(id)\n const steps = definition.steps\n if (!steps || steps.length === 0) throw new Error(`Workflow \"${id}\" does not support stepwise execution`)\n if (opts.stepIndex < 0 || opts.stepIndex >= steps.length) {\n throw new Error(`Step index ${opts.stepIndex} is out of range for \"${id}\" (${steps.length} steps)`)\n }\n const options = opts.options ?? {}\n const input = definition.inputSchema.parse(rawInput)\n const apiKey = resolveApiKey(options)\n const apiUrl = resolveApiUrl(options)\n const artifacts = await ArtifactWriter.create(definition.id, definition.title, input as Record<string, unknown>, options.outputDir, options.runId)\n const client = new WorkflowHttpClient(apiUrl, apiKey, options.fetchImpl, options.headers)\n const ctx: WorkflowRunContext = { runId: artifacts.runId, startedAt: artifacts.startedAt, client, artifacts, signal: options.signal }\n const state = opts.state ?? (definition.createState ? definition.createState(input) : {})\n const step = steps[opts.stepIndex]\n const outcome = await step.run({ input, state, ctx })\n const writtenArtifacts: WorkflowStepArtifact[] = await Promise.all(\n artifacts.artifacts.map(async (artifact) => ({\n ...artifact,\n content: await readFile(artifact.path, 'utf8').catch(() => ''),\n })),\n )\n return {\n runId: artifacts.runId,\n workflowId: definition.id,\n title: definition.title,\n stepIndex: opts.stepIndex,\n stepId: step.id,\n stepTitle: step.title,\n totalSteps: steps.length,\n isLast: opts.stepIndex === steps.length - 1,\n output: outcome.output,\n state: outcome.state,\n warnings: outcome.warnings ?? [],\n summary: outcome.summary ?? null,\n artifacts: writtenArtifacts,\n }\n}\n\nexport { findWorkflowReport, listWorkflowReports, openWorkflowReport }\nexport { z }\n","import type { WorkflowApiClient } from './types.js'\n\nexport class WorkflowHttpClient implements WorkflowApiClient {\n constructor(\n private readonly apiUrl: string,\n private readonly apiKey: string,\n private readonly fetchImpl: typeof fetch = fetch,\n private readonly extraHeaders: Record<string, string> = {},\n ) {}\n\n async post<T>(path: string, body: Record<string, unknown>, timeoutMs = 180_000): Promise<T> {\n const res = await this.fetchImpl(`${this.apiUrl.replace(/\\/$/, '')}${path}`, {\n method: 'POST',\n headers: {\n ...this.extraHeaders,\n 'Content-Type': 'application/json',\n 'x-api-key': this.apiKey,\n },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(timeoutMs),\n })\n const data = await res.json().catch(() => ({}))\n if (!res.ok) {\n const message = typeof (data as { error?: unknown }).error === 'string'\n ? (data as { error: string }).error\n : `Workflow API ${path} failed with ${res.status}`\n throw new Error(message)\n }\n return data as T\n }\n}\n","import { z } from 'zod'\nimport { renderWorkflowReport } from '../report-renderer.js'\nimport type { WorkflowDefinition, WorkflowStepOutcome } from '../types.js'\n\nconst AgentPacketInputSchema = z.object({\n keyword: z.string().min(1),\n domain: z.string().optional(),\n location: z.string().optional(),\n maxQuestions: z.number().int().min(1).max(200).default(40),\n includeSerp: z.boolean().default(true),\n includePaa: z.boolean().default(true),\n includeAiOverview: z.boolean().default(true),\n returnPartial: z.boolean().default(true),\n})\n\ntype AgentPacketInput = z.infer<typeof AgentPacketInputSchema>\n\ninterface OrganicResult {\n position: number\n title: string\n url: string\n domain: string\n snippet?: string | null\n}\n\ninterface PaaRow {\n question: string\n answer?: string | null\n source_title?: string | null\n source_site?: string | null\n source_cite?: string | null\n}\n\ninterface HarvestLike {\n organicResults?: OrganicResult[]\n localPack?: Array<{ position: number; name: string; rating?: string | null; reviewCount?: string | null; websiteUrl?: string | null }>\n flat?: PaaRow[]\n aiOverview?: { detected?: boolean; text?: string | null; citations?: Array<{ text?: string; href?: string }> }\n}\n\nfunction normalizeDomain(value?: string | null): string | null {\n if (!value) return null\n try {\n const url = new URL(value.includes('://') ? value : `https://${value}`)\n return url.hostname.replace(/^www\\./, '').toLowerCase()\n } catch {\n return value.replace(/^https?:\\/\\//, '').replace(/^www\\./, '').split('/')[0]?.toLowerCase() || null\n }\n}\n\nfunction domainFromUrl(url: string): string {\n return normalizeDomain(url) ?? ''\n}\n\nfunction sourceRows(input: AgentPacketInput, serp: HarvestLike | null, paa: HarvestLike | null): Array<Record<string, unknown>> {\n const target = normalizeDomain(input.domain)\n const rows: Array<Record<string, unknown>> = []\n for (const result of serp?.organicResults ?? []) {\n const domain = normalizeDomain(result.domain) ?? domainFromUrl(result.url)\n rows.push({\n surface: 'organic',\n position: result.position,\n title: result.title,\n url: result.url,\n domain,\n question: '',\n answer_excerpt: result.snippet ?? '',\n is_target: target ? domain === target : false,\n is_competitor: target ? domain !== target : true,\n })\n }\n for (const row of paa?.flat ?? []) {\n const url = row.source_cite ?? ''\n const domain = normalizeDomain(row.source_site ?? '') ?? (url ? domainFromUrl(url) : '')\n rows.push({\n surface: 'paa',\n position: '',\n title: row.source_title ?? row.source_site ?? '',\n url,\n domain,\n question: row.question,\n answer_excerpt: (row.answer ?? '').slice(0, 240),\n is_target: target ? domain === target : false,\n is_competitor: target ? Boolean(domain && domain !== target) : Boolean(domain),\n })\n }\n for (const [i, cite] of (serp?.aiOverview?.citations ?? []).entries()) {\n const url = cite.href ?? ''\n const domain = url ? domainFromUrl(url) : ''\n rows.push({\n surface: 'ai_overview',\n position: i + 1,\n title: cite.text ?? '',\n url,\n domain,\n question: '',\n answer_excerpt: '',\n is_target: target ? domain === target : false,\n is_competitor: target ? Boolean(domain && domain !== target) : Boolean(domain),\n })\n }\n return rows\n}\n\nfunction competitorRows(rows: Array<Record<string, unknown>>, targetDomain: string | null): Array<Record<string, unknown>> {\n const byDomain = new Map<string, { organic: number[]; paa: number; ai: number; urls: Set<string> }>()\n for (const row of rows) {\n const domain = String(row.domain ?? '')\n if (!domain || domain === targetDomain) continue\n const entry = byDomain.get(domain) ?? { organic: [], paa: 0, ai: 0, urls: new Set<string>() }\n if (row.surface === 'organic' && row.position) entry.organic.push(Number(row.position))\n if (row.surface === 'paa') entry.paa += 1\n if (row.surface === 'ai_overview') entry.ai += 1\n if (row.url) entry.urls.add(String(row.url))\n byDomain.set(domain, entry)\n }\n return [...byDomain.entries()]\n .map(([domain, entry]) => ({\n domain,\n organic_best_position: entry.organic.length ? Math.min(...entry.organic) : '',\n organic_count: entry.organic.length,\n paa_mentions: entry.paa,\n ai_overview_citations: entry.ai,\n source_url_count: entry.urls.size,\n }))\n .sort((a, b) => Number(a.organic_best_position || 999) - Number(b.organic_best_position || 999))\n}\n\ninterface AgentPacketState {\n serp: HarvestLike | null\n paa: HarvestLike | null\n warnings: string[]\n}\n\nexport const agentPacketWorkflowDefinition: WorkflowDefinition<AgentPacketInput, AgentPacketState> = {\n id: 'agent-packet',\n title: 'Agent-Ready SEO Packet',\n description: 'Create an evidence folder for AI agents from live SERP/PAA/AI search surfaces.',\n inputSchema: AgentPacketInputSchema,\n createState: (): AgentPacketState => ({ serp: null, paa: null, warnings: [] }),\n steps: [\n {\n id: 'harvest-serp',\n title: 'Harvest organic SERP + AI Overview',\n async run({ input, state, ctx }): Promise<WorkflowStepOutcome<AgentPacketState>> {\n if (!input.includeSerp) {\n return { state, output: { skipped: true, reason: 'includeSerp is false' } }\n }\n try {\n const serp = await ctx.client.post<HarvestLike>('/harvest/sync', {\n query: input.keyword,\n location: input.location,\n serpOnly: true,\n maxQuestions: 1,\n format: 'json',\n }, 180_000)\n await ctx.artifacts.writeJson('SERP raw JSON', 'raw/serp.json', serp)\n return {\n state: { ...state, serp },\n output: {\n organicResults: serp.organicResults?.length ?? 0,\n localPack: serp.localPack?.length ?? 0,\n aiOverviewDetected: Boolean(serp.aiOverview?.detected),\n aiOverviewCitations: serp.aiOverview?.citations?.length ?? 0,\n },\n }\n } catch (err) {\n const message = `SERP evidence unavailable: ${err instanceof Error ? err.message : String(err)}`\n return { state: { ...state, warnings: [...state.warnings, message] }, output: { error: message }, warnings: [message] }\n }\n },\n },\n {\n id: 'harvest-paa',\n title: 'Harvest People Also Ask',\n async run({ input, state, ctx }): Promise<WorkflowStepOutcome<AgentPacketState>> {\n if (!input.includePaa) {\n return { state, output: { skipped: true, reason: 'includePaa is false' } }\n }\n try {\n const paa = await ctx.client.post<HarvestLike>('/harvest/sync', {\n query: input.keyword,\n location: input.location,\n maxQuestions: input.maxQuestions,\n format: 'json',\n }, 280_000)\n await ctx.artifacts.writeJson('PAA raw JSON', 'raw/paa.json', paa)\n return {\n state: { ...state, paa },\n output: { paaQuestions: paa.flat?.length ?? 0 },\n }\n } catch (err) {\n const message = `PAA evidence unavailable: ${err instanceof Error ? err.message : String(err)}`\n return { state: { ...state, warnings: [...state.warnings, message] }, output: { error: message }, warnings: [message] }\n }\n },\n },\n {\n id: 'assemble',\n title: 'Assemble evidence packet',\n async run({ input, state, ctx }): Promise<WorkflowStepOutcome<AgentPacketState>> {\n const { serp, paa } = state\n const warnings = state.warnings\n if (!serp && !paa && !input.returnPartial) throw new Error('No SEO evidence was collected')\n const rows = sourceRows(input, serp, paa)\n const target = normalizeDomain(input.domain)\n const competitors = competitorRows(rows, target)\n const evidence = {\n input,\n serp: serp ?? { status: 'skipped' },\n paa: paa ?? { status: 'skipped' },\n target: {\n domain: target,\n organicPositions: rows.filter(r => r.surface === 'organic' && r.is_target).map(r => Number(r.position)),\n citedInAiOverview: rows.some(r => r.surface === 'ai_overview' && r.is_target),\n citedInPaa: rows.some(r => r.surface === 'paa' && r.is_target),\n },\n competitors,\n warnings,\n }\n\n await ctx.artifacts.writeJson('Evidence JSON', 'evidence.json', evidence)\n await ctx.artifacts.writeCsv('Sources CSV', 'sources.csv', ['surface', 'position', 'title', 'url', 'domain', 'question', 'answer_excerpt', 'is_target', 'is_competitor'], rows)\n await ctx.artifacts.writeCsv('Competitors CSV', 'competitors.csv', ['domain', 'organic_best_position', 'organic_count', 'paa_mentions', 'ai_overview_citations', 'source_url_count'], competitors)\n\n const brief = [\n `# SEO Evidence Brief: ${input.keyword}`,\n '',\n `Location: ${input.location ?? 'not specified'}`,\n `Target domain: ${target ?? 'not specified'}`,\n '',\n '## Evidence Summary',\n `- Organic rows: ${rows.filter(r => r.surface === 'organic').length}`,\n `- PAA rows: ${rows.filter(r => r.surface === 'paa').length}`,\n `- AI Overview citations: ${rows.filter(r => r.surface === 'ai_overview').length}`,\n `- Competitor domains: ${competitors.length}`,\n '',\n '## Recommended Use',\n 'Use the CSV files as source of truth. Tie content recommendations to evidence rows and mark unsupported ideas as assumptions.',\n ].join('\\n')\n await ctx.artifacts.writeText('Brief', 'brief.md', brief)\n await ctx.artifacts.writeText('Agent tasks', 'tasks.md', [\n '# Agent Tasks',\n '',\n '- [ ] Read `evidence.json` before writing recommendations.',\n '- [ ] Compare the target domain against `competitors.csv`.',\n '- [ ] Use `sources.csv` for citations and source-grounded page sections.',\n '- [ ] Mark unsupported recommendations as assumptions.',\n ].join('\\n'))\n await ctx.artifacts.writeText('Agent instructions', 'agent-instructions.md', [\n '# Agent Instructions',\n '',\n 'You are working from an MCP Scraper SEO evidence packet. Use `evidence.json` and CSV files as source of truth. Do not invent citations. If a recommendation is not supported by evidence, mark it as an assumption.',\n ].join('\\n'))\n\n const summary = `${rows.length} evidence rows and ${competitors.length} competitor domains collected.`\n const reportPath = await ctx.artifacts.writeHtml('HTML report', 'report.html', renderWorkflowReport({\n title: 'Agent-Ready SEO Packet',\n subtitle: `${input.keyword}${input.location ? ` · ${input.location}` : ''}`,\n summary,\n warnings,\n tables: [\n { title: 'Competitor Domains', columns: ['domain', 'organic_best_position', 'organic_count', 'paa_mentions', 'ai_overview_citations', 'source_url_count'], rows: competitors.slice(0, 50) },\n { title: 'Evidence Sources', columns: ['surface', 'position', 'title', 'domain', 'question', 'is_target'], rows: rows.slice(0, 100) },\n ],\n }))\n const status = warnings.length ? 'partial' : 'succeeded'\n const counts = { sources: rows.length, competitors: competitors.length }\n await ctx.artifacts.writeManifest(status, counts, warnings, [])\n return {\n state,\n output: { sources: rows.length, competitors: competitors.length, status },\n summary: { title: 'Agent-Ready SEO Packet', summary, status, counts, warnings, errors: [], reportPath },\n }\n },\n },\n ],\n}\n\n","export interface ReportTable {\n title: string\n columns: string[]\n rows: Array<Record<string, unknown>>\n}\n\nexport interface ReportSection {\n title: string\n body: string\n}\n\nexport interface WorkflowReportInput {\n title: string\n subtitle?: string\n summary: string\n sections?: ReportSection[]\n tables?: ReportTable[]\n warnings?: string[]\n}\n\nexport function escapeHtml(value: unknown): string {\n return String(value ?? '')\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;')\n}\n\nfunction renderTable(table: ReportTable): string {\n const rows = table.rows.map(row => (\n `<tr>${table.columns.map(col => `<td>${escapeHtml(row[col])}</td>`).join('')}</tr>`\n )).join('\\n')\n return [\n `<section>`,\n `<h2>${escapeHtml(table.title)}</h2>`,\n `<div class=\"table-wrap\"><table>`,\n `<thead><tr>${table.columns.map(col => `<th>${escapeHtml(col)}</th>`).join('')}</tr></thead>`,\n `<tbody>${rows || `<tr><td colspan=\"${table.columns.length}\">No rows</td></tr>`}</tbody>`,\n `</table></div>`,\n `</section>`,\n ].join('\\n')\n}\n\nexport function renderWorkflowReport(input: WorkflowReportInput): string {\n const warnings = input.warnings?.length\n ? `<section class=\"warnings\"><h2>Warnings</h2><ul>${input.warnings.map(w => `<li>${escapeHtml(w)}</li>`).join('')}</ul></section>`\n : ''\n const sections = (input.sections ?? []).map(section => (\n `<section><h2>${escapeHtml(section.title)}</h2><p>${escapeHtml(section.body)}</p></section>`\n )).join('\\n')\n const tables = (input.tables ?? []).map(renderTable).join('\\n')\n\n return [\n '<!doctype html>',\n '<html lang=\"en\">',\n '<head>',\n '<meta charset=\"utf-8\">',\n '<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">',\n `<title>${escapeHtml(input.title)}</title>`,\n '<style>',\n ':root{font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,\"Segoe UI\",sans-serif;color:#172026;background:#f6f7f8}',\n 'body{margin:0;padding:32px}main{max-width:1180px;margin:0 auto;background:#fff;border:1px solid #d9dee3;border-radius:8px;padding:28px}',\n 'h1{font-size:30px;line-height:1.15;margin:0 0 8px}h2{font-size:18px;margin:28px 0 12px}p{line-height:1.55;color:#3d4952}.sub{color:#66737f;margin:0 0 20px}',\n '.summary{background:#eef6f8;border-left:4px solid #12829a;padding:14px 16px;margin:20px 0}.warnings{background:#fff7e8;border-left:4px solid #c87b00;padding:12px 16px}',\n '.table-wrap{overflow:auto;border:1px solid #dfe5ea;border-radius:8px}table{border-collapse:collapse;width:100%;font-size:13px}th,td{border-bottom:1px solid #edf0f2;padding:9px 10px;text-align:left;vertical-align:top}th{background:#f3f5f7;color:#31404c;position:sticky;top:0}tr:last-child td{border-bottom:0}',\n '</style>',\n '</head>',\n '<body><main>',\n `<h1>${escapeHtml(input.title)}</h1>`,\n input.subtitle ? `<p class=\"sub\">${escapeHtml(input.subtitle)}</p>` : '',\n `<div class=\"summary\">${escapeHtml(input.summary)}</div>`,\n warnings,\n sections,\n tables,\n '</main></body></html>',\n ].join('\\n')\n}\n\n","import { z } from 'zod'\nimport { renderWorkflowReport } from '../report-renderer.js'\nimport type { WorkflowDefinition, WorkflowRunContext, WorkflowRunSummary } from '../types.js'\nimport { DEFAULT_MAPS_PROXY_MODE } from '../../schemas.js'\n\nconst DirectoryWorkflowCliInputSchema = z.object({\n query: z.string().min(1),\n state: z.string().min(2).default('TN'),\n minPopulation: z.number().int().min(0).default(100_000),\n maxCities: z.number().int().min(1).max(100).default(25),\n maxResultsPerCity: z.number().int().min(1).max(50).default(20),\n concurrency: z.number().int().min(1).max(5).default(5),\n proxyMode: z.enum(['location', 'configured', 'none']).default(DEFAULT_MAPS_PROXY_MODE),\n saveCsv: z.boolean().default(true),\n})\n\ntype DirectoryWorkflowCliInput = z.infer<typeof DirectoryWorkflowCliInputSchema>\n\ninterface DirectoryBusiness {\n position: number\n name: string\n rating: string | null\n reviewCount: string | null\n category: string | null\n address: string | null\n phone: string | null\n websiteUrl: string | null\n placeUrl: string\n cid: string | null\n cidDecimal: string | null\n}\n\ninterface DirectoryCity {\n city: string\n state: string\n location: string\n population: number\n status: 'ok' | 'empty' | 'failed'\n error: string | null\n resultCount: number\n results: DirectoryBusiness[]\n}\n\nexport interface DirectoryWorkflowApiResult {\n query: string\n state: string\n selectedCityCount: number\n totalResultCount: number\n warnings: string[]\n csvPath: string | null\n cities: DirectoryCity[]\n}\n\nexport function directoryRows(result: DirectoryWorkflowApiResult): Array<Record<string, unknown>> {\n const rows: Array<Record<string, unknown>> = []\n for (const city of result.cities) {\n if (!city.results.length) {\n rows.push({\n source_query: result.query,\n source_location: city.location,\n city: city.city,\n state: city.state,\n population: city.population,\n result_position: null,\n business_name: null,\n review_stars: null,\n review_count: null,\n category: null,\n address: null,\n phone: null,\n website_url: null,\n place_url: null,\n cid: null,\n cid_decimal: null,\n result_status: city.status,\n error: city.error,\n })\n continue\n }\n for (const business of city.results) {\n rows.push({\n source_query: result.query,\n source_location: city.location,\n city: city.city,\n state: city.state,\n population: city.population,\n result_position: business.position,\n business_name: business.name,\n review_stars: business.rating,\n review_count: business.reviewCount,\n category: business.category,\n address: business.address,\n phone: business.phone,\n website_url: business.websiteUrl,\n place_url: business.placeUrl,\n cid: business.cid,\n cid_decimal: business.cidDecimal,\n result_status: city.status,\n error: city.error,\n })\n }\n }\n return rows\n}\n\nexport const DIRECTORY_CSV_HEADERS = [\n 'source_query',\n 'source_location',\n 'city',\n 'state',\n 'population',\n 'result_position',\n 'business_name',\n 'review_stars',\n 'review_count',\n 'category',\n 'address',\n 'phone',\n 'website_url',\n 'place_url',\n 'cid',\n 'cid_decimal',\n 'result_status',\n 'error',\n]\n\nexport const directoryWorkflowDefinition: WorkflowDefinition<DirectoryWorkflowCliInput> = {\n id: 'directory',\n title: 'Directory Workflow',\n description: 'Select city markets and export Google Maps business candidates.',\n inputSchema: DirectoryWorkflowCliInputSchema,\n async run(input: DirectoryWorkflowCliInput, ctx: WorkflowRunContext): Promise<WorkflowRunSummary> {\n await ctx.artifacts.writeManifest('running', {}, [], [])\n const result = await ctx.client.post<DirectoryWorkflowApiResult>('/directory/run', input as Record<string, unknown>, 900_000)\n await ctx.artifacts.writeJson('Directory evidence', 'evidence.json', result)\n const rows = directoryRows(result)\n await ctx.artifacts.writeCsv('Directory CSV', 'exports/directory.csv', DIRECTORY_CSV_HEADERS, rows)\n\n const cityRows = result.cities.map(city => ({\n city: city.city,\n state: city.state,\n population: city.population,\n status: city.status,\n result_count: city.resultCount,\n error: city.error ?? '',\n }))\n const topRows = rows\n .filter(row => row.business_name)\n .slice(0, 100)\n .map(row => ({\n city: row.city,\n position: row.result_position,\n business: row.business_name,\n rating: row.review_stars,\n reviews: row.review_count,\n category: row.category,\n website: row.website_url,\n }))\n\n const summary = `${result.selectedCityCount} cities processed with ${result.totalResultCount} Maps results.`\n await ctx.artifacts.writeText('Summary', 'summary.md', `# Directory Workflow\\n\\n${summary}\\n`)\n const reportPath = await ctx.artifacts.writeHtml('HTML report', 'report.html', renderWorkflowReport({\n title: 'Directory Workflow',\n subtitle: `${input.query} · ${input.state}`,\n summary,\n warnings: result.warnings,\n tables: [\n { title: 'Cities', columns: ['city', 'state', 'population', 'status', 'result_count', 'error'], rows: cityRows },\n { title: 'Top Results', columns: ['city', 'position', 'business', 'rating', 'reviews', 'category', 'website'], rows: topRows },\n ],\n }))\n const status = result.cities.some(city => city.status === 'failed') ? 'partial' : 'succeeded'\n const counts = { cities: result.selectedCityCount, results: result.totalResultCount, rows: rows.length }\n await ctx.artifacts.writeManifest(status, counts, result.warnings, [])\n return { title: 'Directory Workflow', summary, status, counts, warnings: result.warnings, errors: [], reportPath }\n },\n}\n","import { z } from 'zod'\n\nexport const DEFAULT_PROXY_MODE = 'none' as const\nexport const DEFAULT_MAPS_PROXY_MODE = 'location' as const\n\nexport const HarvestOptionsSchema = z.object({\n query: z.string().min(1),\n location: z.string().optional(),\n gl: z.string().length(2).default('us'),\n hl: z.string().length(2).default('en'),\n device: z.enum(['desktop', 'mobile']).default('desktop'),\n proxyMode: z.enum(['location', 'configured', 'none']).default(DEFAULT_PROXY_MODE),\n proxyZip: z.string().regex(/^\\d{5}$/).optional(),\n debug: z.boolean().default(false),\n depth: z.number().int().min(1).max(30).default(3),\n maxQuestions: z.number().int().min(1).max(1000).default(100),\n headless: z.boolean().default(false),\n profileDir: z.string().optional(),\n proxy: z.string().url().optional(),\n kernelApiKey: z.string().optional(),\n kernelProxyId: z.string().optional(),\n kernelProxyResolution: z.unknown().optional(),\n outputDir: z.string().default('./paa-output'),\n format: z.enum(['json', 'csv', 'both']).default('both'),\n serpOnly: z.boolean().default(false),\n pages: z.number().int().min(1).max(2).default(1),\n softDeadlineMs: z.number().optional(),\n})\n\nexport const MapsPlaceOptionsSchema = z.object({\n businessName: z.string().min(1),\n location: z.string().min(1),\n gl: z.string().length(2).default('us'),\n hl: z.string().length(2).default('en'),\n includeReviews: z.boolean().default(false),\n maxReviews: z.number().int().min(1).max(500).default(50),\n includeServices: z.boolean().default(false),\n kernelApiKey: z.string().optional(),\n kernelProxyId: z.string().optional(),\n headless: z.boolean().default(true),\n})\n\nexport const MapsSearchOptionsSchema = z.object({\n query: z.string().min(1),\n location: z.string().optional(),\n gl: z.string().length(2).default('us'),\n hl: z.string().length(2).default('en'),\n maxResults: z.number().int().min(1).max(50).default(10),\n proxyMode: z.enum(['location', 'configured', 'none']).default(DEFAULT_MAPS_PROXY_MODE),\n proxyZip: z.string().regex(/^\\d{5}$/).optional(),\n debug: z.boolean().default(false),\n kernelApiKey: z.string().optional(),\n kernelProxyId: z.string().optional(),\n kernelProxyResolution: z.unknown().optional(),\n headless: z.boolean().default(true),\n})\n\nexport const RawPAAItemSchema = z.object({\n question: z.string().min(1),\n answer: z.string().optional(),\n sourceTitle: z.string().optional(),\n sourceSite: z.string().optional(),\n sourceCite: z.string().optional(),\n})\n\nexport const RawMapsOverviewSchema = z.object({\n name: z.string().nullable(),\n rating: z.string().nullable(),\n reviewCount: z.string().nullable(),\n category: z.string().nullable(),\n address: z.string().nullable(),\n hoursSummary: z.string().nullable(),\n phone: z.string().nullable(),\n phoneDisplay: z.string().nullable(),\n website: z.string().nullable(),\n plusCode: z.string().nullable(),\n bookingUrl: z.string().nullable(),\n})\n\nexport const RawMapsHoursRowSchema = z.object({\n day: z.string(),\n hours: z.string(),\n})\n\nexport const RawMapsReviewStatsSchema = z.object({\n reviewHistogram: z.array(z.object({\n stars: z.number(),\n count: z.string(),\n })),\n reviewTopics: z.array(z.object({\n label: z.string(),\n count: z.string(),\n })),\n})\n\nexport const RawMapsReviewCardSchema = z.object({\n reviewId: z.string(),\n author: z.string().nullable(),\n stars: z.string().nullable(),\n date: z.string().nullable(),\n text: z.string().nullable(),\n ownerResponse: z.string().nullable(),\n})\n\nexport const RawMapsAboutAttributeSchema = z.object({\n section: z.string(),\n attribute: z.string(),\n})\n","import { z } from 'zod'\nimport { renderWorkflowReport } from '../report-renderer.js'\nimport type { WorkflowDefinition, WorkflowRunContext, WorkflowRunSummary } from '../types.js'\nimport { DEFAULT_MAPS_PROXY_MODE } from '../../schemas.js'\n\nconst GetLeadsInputSchema = z.object({\n query: z.string().min(1).describe('Business category, niche, or keyword to search on Google Maps, e.g. \"roofers\", \"med spas\", \"dentists\". Do not include the city here.'),\n location: z.string().min(1).describe('City / market to search, e.g. \"Houston, TX\" or \"Austin, Texas\".'),\n maxResults: z.number().int().min(1).max(50).default(25).describe('How many Maps businesses to collect for the market. Maximum 50.'),\n enrichWebsites: z.boolean().default(true).describe('Visit each business website (home + contact pages) to harvest email and social links. Uses the proxy/browser-backed extractor so blocked sites still resolve.'),\n hydrateReviewCounts: z.boolean().default(true).describe('Deep-dive each profile to confirm the review count and booking URL that the Maps search list omits.'),\n concurrency: z.number().int().min(1).max(4).default(3).describe('How many businesses to enrich in parallel. Keep low to respect per-account concurrency limits.'),\n proxyMode: z.enum(['location', 'configured', 'none']).default(DEFAULT_MAPS_PROXY_MODE).describe('Proxy targeting for the Maps search. location targets the market; none is for local debugging.'),\n})\n\ntype GetLeadsInput = z.infer<typeof GetLeadsInputSchema>\n\ninterface MapsSearchApiResult {\n query: string\n location: string | null\n searchQuery: string\n resultCount: number\n results: Array<{\n position: number\n name: string\n placeUrl: string\n cid: string | null\n cidDecimal: string | null\n rating: string | null\n reviewCount: string | null\n category: string | null\n address: string | null\n phone: string | null\n hoursStatus: string | null\n websiteUrl: string | null\n directionsUrl: string | null\n metadata: string[]\n }>\n}\n\ninterface MapsPlaceApiResult {\n name: string | null\n rating: string | null\n reviewCount: string | null\n category: string | null\n website: string | null\n phone?: string | null\n address?: string | null\n bookingUrl?: string | null\n}\n\ninterface ExtractUrlApiResult {\n title?: string | null\n bodyHtml?: string | null\n bodyMarkdown?: string | null\n}\n\ninterface LeadRow {\n position: number\n business_name: string\n review_stars: string\n review_count: string\n category: string\n address: string\n phone: string\n website: string\n email: string\n email_domain_match: string\n email_status: string\n socials: string\n booking_url: string\n place_url: string\n cid: string\n source_location: string\n [key: string]: string | number\n}\n\nconst LEADS_CSV_HEADERS = [\n 'position', 'business_name', 'review_stars', 'review_count', 'category', 'address', 'phone',\n 'website', 'email', 'email_domain_match', 'email_status', 'socials', 'booking_url', 'place_url', 'cid', 'source_location',\n]\n\nconst EMAIL_RE = /[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}/g\nconst MAILTO_RE = /mailto:([^\"'?>\\s]+)/gi\nconst SOCIAL_RE = /https?:\\/\\/(?:www\\.)?(?:facebook|instagram|linkedin|twitter|youtube|tiktok)\\.com\\/[^\\s\"'<>)]+/gi\nconst EMAIL_BAD = ['.png', '.jpg', '.jpeg', '.gif', '.svg', '.webp', '.ico', 'sentry', 'wix.com', 'wixpress', 'example.', 'godaddy', 'squarespace', 'schema.org', '@2x', 'u003e', 'core-js']\nconst EMAIL_PREFIX = ['info@', 'office@', 'contact@', 'sales@', 'hello@', 'admin@', 'service@', 'support@']\nconst SOCIAL_SKIP = ['/sharer', '/share?', '/intent/', 'plugins/', '/dialog/', 'platform.', 'badge', 'developers.']\n\nasync function mapLimit<T, R>(items: T[], limit: number, fn: (item: T, index: number) => Promise<R>): Promise<R[]> {\n const out: R[] = new Array(items.length)\n let next = 0\n async function worker(): Promise<void> {\n while (next < items.length) {\n const index = next\n next += 1\n out[index] = await fn(items[index], index)\n }\n }\n await Promise.all(Array.from({ length: Math.min(limit, items.length) }, () => worker()))\n return out\n}\n\nfunction hostRoot(url: string): string {\n try {\n return new URL(url).hostname.replace(/^www\\./, '').split('.')[0].toLowerCase()\n } catch {\n return ''\n }\n}\n\nfunction cleanEmails(raw: string[]): string[] {\n const out = new Set<string>()\n for (const value of raw) {\n const email = value.trim().toLowerCase().replace(/\\.$/, '')\n if (email.split('@').length !== 2) continue\n if (email.length > 60) continue\n if (EMAIL_BAD.some(bad => email.includes(bad))) continue\n out.add(email)\n }\n return [...out]\n}\n\nfunction pickEmail(emails: string[], host: string): string {\n if (!emails.length) return ''\n const root = hostRoot(host)\n for (const prefix of EMAIL_PREFIX) {\n const hit = emails.find(e => e.startsWith(prefix) && root && e.split('@')[1].includes(root))\n if (hit) return hit\n }\n const domainHit = emails.find(e => root && e.split('@')[1].includes(root))\n if (domainHit) return domainHit\n for (const prefix of EMAIL_PREFIX) {\n const hit = emails.find(e => e.startsWith(prefix))\n if (hit) return hit\n }\n return emails[0]\n}\n\nfunction parseContacts(html: string): { emails: string[]; socials: string[] } {\n const mailtos = [...html.matchAll(MAILTO_RE)].map(m => decodeURIComponent(m[1]).split('?')[0])\n const inline = html.match(EMAIL_RE) ?? []\n const emails = cleanEmails([...mailtos, ...inline])\n const socials = [...new Set((html.match(SOCIAL_RE) ?? [])\n .map(s => s.replace(/[)\"'<>]+$/, ''))\n .filter(s => !SOCIAL_SKIP.some(skip => s.toLowerCase().includes(skip))))]\n .slice(0, 5)\n return { emails, socials }\n}\n\nfunction buildAttemptUrls(website: string): string[] {\n const urls = new Set<string>()\n urls.add(website)\n try {\n const origin = new URL(website).origin\n urls.add(`${origin}/contact`)\n urls.add(`${origin}/contact-us`)\n } catch {\n return [...urls]\n }\n return [...urls].slice(0, 3)\n}\n\nexport const getLeadsWorkflowDefinition: WorkflowDefinition<GetLeadsInput> = {\n id: 'get-leads',\n title: 'Get Leads',\n description: 'Build an outreach-ready local lead list: Google Maps search for a niche in a market, confirm review counts + booking URLs, then visit each business website (home + contact) to harvest email and social links, with proxy/browser-backed extraction so blocked sites still resolve. Saves a leads CSV.',\n inputSchema: GetLeadsInputSchema,\n async run(input: GetLeadsInput, ctx: WorkflowRunContext): Promise<WorkflowRunSummary> {\n await ctx.artifacts.writeManifest('running', {}, [], [])\n const warnings: string[] = []\n const errors: string[] = []\n\n const search = await ctx.client.post<MapsSearchApiResult>('/maps/search', {\n query: input.query,\n location: input.location,\n maxResults: input.maxResults,\n proxyMode: input.proxyMode,\n }, 180_000)\n await ctx.artifacts.writeJson('Maps search raw', 'raw/maps-search.json', search)\n\n const seen = new Set<string>()\n const deduped = search.results.filter(result => {\n const key = result.cid ?? result.placeUrl ?? result.name.toLowerCase()\n if (seen.has(key)) return false\n seen.add(key)\n return true\n })\n\n const rows = await mapLimit(deduped, input.concurrency, async (result): Promise<LeadRow> => {\n let reviewCount = result.reviewCount ?? ''\n let bookingUrl = ''\n let website = result.websiteUrl ?? ''\n\n if (input.hydrateReviewCounts) {\n try {\n const place = await ctx.client.post<MapsPlaceApiResult>('/maps/place', {\n businessName: result.name,\n location: input.location,\n includeReviews: false,\n }, 180_000)\n reviewCount = place.reviewCount ?? reviewCount\n bookingUrl = place.bookingUrl ?? ''\n website = website || (place.website ?? '')\n } catch (err) {\n warnings.push(`Review hydration failed for ${result.name}: ${err instanceof Error ? err.message : String(err)}`)\n }\n }\n\n let email = ''\n let socials: string[] = []\n let emailStatus = website ? 'no email found' : 'no website'\n let domainMatch = ''\n\n if (input.enrichWebsites && website) {\n const attempts = buildAttemptUrls(website)\n let reached = false\n const allEmails: string[] = []\n const allSocials = new Set<string>()\n for (const attemptUrl of attempts) {\n try {\n const page = await ctx.client.post<ExtractUrlApiResult>('/extract-url', { url: attemptUrl }, 120_000)\n reached = true\n const parsed = parseContacts(page.bodyHtml ?? page.bodyMarkdown ?? '')\n allEmails.push(...parsed.emails)\n parsed.socials.forEach(s => allSocials.add(s))\n if (parsed.emails.length) break\n } catch {\n continue\n }\n }\n socials = [...allSocials].slice(0, 5)\n email = pickEmail([...new Set(allEmails)], website)\n if (email) {\n domainMatch = hostRoot(website) && email.split('@')[1].includes(hostRoot(website)) ? 'yes' : 'NO-verify'\n emailStatus = domainMatch === 'yes' ? 'ok' : 'ok (off-domain — verify)'\n } else if (!reached) {\n emailStatus = 'site unreachable'\n } else if (socials.length) {\n emailStatus = 'form/social only'\n }\n }\n\n return {\n position: result.position,\n business_name: result.name,\n review_stars: result.rating ?? '',\n review_count: reviewCount,\n category: result.category ?? '',\n address: result.address ?? '',\n phone: result.phone ?? '',\n website,\n email,\n email_domain_match: domainMatch,\n email_status: emailStatus,\n socials: socials.join(' ; '),\n booking_url: bookingUrl,\n place_url: result.placeUrl,\n cid: result.cid ?? '',\n source_location: input.location,\n }\n })\n\n await ctx.artifacts.writeCsv('Leads CSV', 'exports/leads.csv', LEADS_CSV_HEADERS, rows)\n await ctx.artifacts.writeJson('Leads evidence', 'evidence.json', { input, search: { query: search.searchQuery, resultCount: search.resultCount }, rows })\n\n const withEmail = rows.filter(r => r.email).length\n const domainMatched = rows.filter(r => r.email_domain_match === 'yes').length\n const withReviewCount = rows.filter(r => r.review_count).length\n const withSocials = rows.filter(r => r.socials).length\n const withWebsite = rows.filter(r => r.website).length\n\n const summary = `${rows.length} ${input.query} in ${input.location}: ${withEmail} emails (${domainMatched} domain-matched), ${withReviewCount} review counts, ${withSocials} with socials.`\n await ctx.artifacts.writeText('Summary', 'summary.md', `# Get Leads\\n\\n${summary}\\n`)\n await ctx.artifacts.writeText('Agent tasks', 'tasks.md', [\n '# Get Leads — next steps',\n '',\n '- [ ] Verify deliverability of the harvested emails before outreach (MX/SMTP check).',\n '- [ ] For \"form/social only\" rows, use the website contact form or the captured social profile.',\n '- [ ] Treat \"off-domain — verify\" emails with care; they may belong to a web developer or parent brand.',\n '- [ ] Respect CAN-SPAM / GDPR — scraped contact data is not consent to email.',\n ].join('\\n'))\n\n const reportPath = await ctx.artifacts.writeHtml('HTML report', 'report.html', renderWorkflowReport({\n title: 'Get Leads',\n subtitle: `${input.query} · ${input.location}`,\n summary,\n warnings,\n tables: [\n {\n title: 'Leads',\n columns: ['position', 'business_name', 'review_stars', 'review_count', 'phone', 'website', 'email', 'email_status', 'socials', 'booking_url'],\n rows,\n },\n ],\n }))\n\n const status: WorkflowRunSummary['status'] = errors.length ? 'failed' : warnings.length ? 'partial' : 'succeeded'\n const counts = {\n businesses: rows.length,\n withWebsite,\n emails: withEmail,\n domainMatchedEmails: domainMatched,\n reviewCounts: withReviewCount,\n withSocials,\n }\n await ctx.artifacts.writeManifest(status, counts, warnings, errors)\n return { title: 'Get Leads', summary, status, counts, warnings, errors, reportPath }\n },\n}\n","import { z } from 'zod'\nimport { renderWorkflowReport } from '../report-renderer.js'\nimport type { WorkflowDefinition, WorkflowRunContext, WorkflowRunSummary } from '../types.js'\nimport { DIRECTORY_CSV_HEADERS, directoryRows, type DirectoryWorkflowApiResult } from './directory.js'\nimport { DEFAULT_MAPS_PROXY_MODE } from '../../schemas.js'\n\nconst LocalCompetitiveAuditInputSchema = z.object({\n query: z.string().min(1),\n state: z.string().min(2).default('TN'),\n minPopulation: z.number().int().min(0).default(100_000),\n maxCities: z.number().int().min(1).max(100).default(25),\n maxResultsPerCity: z.number().int().min(1).max(50).default(20),\n hydrateTop: z.number().int().min(0).max(10).default(5),\n maxReviews: z.number().int().min(0).max(500).default(50),\n concurrency: z.number().int().min(1).max(5).default(5),\n proxyMode: z.enum(['location', 'configured', 'none']).default(DEFAULT_MAPS_PROXY_MODE),\n returnPartial: z.boolean().default(true),\n})\n\ntype LocalCompetitiveAuditInput = z.infer<typeof LocalCompetitiveAuditInputSchema>\n\ninterface MapsPlaceIntelResult {\n name: string | null\n rating: string | null\n reviewCount: string | null\n category: string | null\n website: string | null\n reviewsStatus: string\n reviewHistogram: Array<{ stars: number; count: string }>\n reviewTopics: Array<{ label: string; count: string }>\n aboutAttributes: Array<{ section: string; attribute: string }>\n reviews: Array<{ stars: string | null; text: string | null; ownerResponse: string | null }>\n}\n\nasync function mapLimit<T, R>(items: T[], limit: number, fn: (item: T, index: number) => Promise<R>): Promise<R[]> {\n const out: R[] = new Array(items.length)\n let next = 0\n async function worker(): Promise<void> {\n while (next < items.length) {\n const index = next\n next += 1\n out[index] = await fn(items[index], index)\n }\n }\n await Promise.all(Array.from({ length: Math.min(limit, items.length) }, () => worker()))\n return out\n}\n\nfunction numberFrom(value: unknown): number | null {\n if (value === null || value === undefined || value === '') return null\n const parsed = Number(String(value).replace(/[^\\d.]/g, ''))\n return Number.isFinite(parsed) ? parsed : null\n}\n\nfunction median(values: Array<number | null>): number | null {\n const nums = values.filter((v): v is number => v !== null).sort((a, b) => a - b)\n if (!nums.length) return null\n return nums[Math.floor(nums.length / 2)] ?? null\n}\n\nfunction termsFrom(texts: string[]): string {\n const stop = new Set(['the', 'and', 'for', 'with', 'that', 'this', 'was', 'were', 'are', 'you', 'our', 'they', 'had', 'have', 'not', 'but', 'from', 'very', 'great', 'good'])\n const counts = new Map<string, number>()\n for (const text of texts) {\n for (const token of text.toLowerCase().replace(/[^a-z0-9\\s]/g, ' ').split(/\\s+/)) {\n if (token.length < 4 || stop.has(token)) continue\n counts.set(token, (counts.get(token) ?? 0) + 1)\n }\n }\n return [...counts.entries()].sort((a, b) => b[1] - a[1]).slice(0, 8).map(([term, count]) => `${term} (${count})`).join('; ')\n}\n\nexport const localCompetitiveAuditWorkflowDefinition: WorkflowDefinition<LocalCompetitiveAuditInput> = {\n id: 'local-competitive-audit',\n title: 'Local Competitive Audit',\n description: 'Audit local Maps competitors, categories, review counts, and review themes across city markets.',\n inputSchema: LocalCompetitiveAuditInputSchema,\n async run(input: LocalCompetitiveAuditInput, ctx: WorkflowRunContext): Promise<WorkflowRunSummary> {\n await ctx.artifacts.writeManifest('running', {}, [], [])\n const warnings: string[] = []\n const errors: string[] = []\n const directory = await ctx.client.post<DirectoryWorkflowApiResult>('/directory/run', {\n query: input.query,\n state: input.state,\n minPopulation: input.minPopulation,\n maxCities: input.maxCities,\n maxResultsPerCity: input.maxResultsPerCity,\n concurrency: input.concurrency,\n proxyMode: input.proxyMode,\n saveCsv: true,\n }, 900_000)\n\n await ctx.artifacts.writeJson('Directory raw JSON', 'raw/directory-workflow.json', directory)\n const baseRows = directoryRows(directory)\n await ctx.artifacts.writeCsv('Base directory CSV', 'exports/directory.csv', DIRECTORY_CSV_HEADERS, baseRows)\n\n const selected = directory.cities.flatMap(city =>\n city.results.slice(0, input.hydrateTop).map(result => ({ city, result })),\n )\n const seen = new Set<string>()\n const deduped = selected.filter(({ city, result }) => {\n const key = result.cid ?? result.placeUrl ?? `${city.location}:${result.name.toLowerCase()}`\n if (seen.has(key)) return false\n seen.add(key)\n return true\n })\n\n const hydrated = await mapLimit(deduped, 3, async ({ city, result }, index) => {\n try {\n const detail = await ctx.client.post<MapsPlaceIntelResult>('/maps/place', {\n businessName: result.name,\n location: city.location,\n includeReviews: input.maxReviews > 0,\n maxReviews: Math.max(1, input.maxReviews),\n }, 180_000)\n await ctx.artifacts.writeJson(`${result.name} profile`, `raw/maps-place-intel/${index + 1}-${result.name.toLowerCase().replace(/[^a-z0-9]+/g, '-')}.json`, detail)\n return { city, result, detail, error: null as string | null }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n warnings.push(`Profile hydration failed for ${result.name} (${city.location}): ${message}`)\n return { city, result, detail: null, error: message }\n }\n })\n\n const competitorRows = hydrated.map(({ city, result, detail, error }) => {\n const reviews = detail?.reviews ?? []\n const ownerResponses = reviews.filter(r => r.ownerResponse).length\n return {\n city: city.city,\n state: city.state,\n source_location: city.location,\n result_position: result.position,\n business_name: result.name,\n category: detail?.category ?? result.category,\n review_stars: detail?.rating ?? result.rating,\n review_count: detail?.reviewCount ?? result.reviewCount,\n phone: result.phone,\n website_url: detail?.website ?? result.websiteUrl,\n place_url: result.placeUrl,\n cid: result.cid,\n cid_decimal: result.cidDecimal,\n hydrated: detail ? 'true' : 'false',\n reviews_status: detail?.reviewsStatus ?? '',\n review_topics: (detail?.reviewTopics ?? []).map(t => `${t.label} (${t.count})`).join('; '),\n owner_response_rate: reviews.length ? (ownerResponses / reviews.length).toFixed(2) : '',\n error: error ?? '',\n }\n })\n\n const reviewInsightRows = hydrated.map(({ city, result, detail }) => {\n const reviews = detail?.reviews ?? []\n const positive = reviews.filter(r => Number(r.stars) >= 5 && r.text).map(r => r.text!)\n const negative = reviews.filter(r => Number(r.stars) > 0 && Number(r.stars) <= 3 && r.text).map(r => r.text!)\n return {\n city: city.city,\n business_name: result.name,\n cid: result.cid,\n review_count: detail?.reviewCount ?? result.reviewCount,\n average_rating: detail?.rating ?? result.rating,\n topics: (detail?.reviewTopics ?? []).map(t => `${t.label} (${t.count})`).join('; '),\n praise_terms: termsFrom(positive),\n complaint_terms: termsFrom(negative),\n positive_sample: positive[0]?.slice(0, 280) ?? '',\n negative_sample: negative[0]?.slice(0, 280) ?? '',\n }\n })\n\n const citySummaryRows = directory.cities.map(city => {\n const resultReviewCounts = city.results.map(r => numberFrom(r.reviewCount))\n const resultRatings = city.results.map(r => numberFrom(r.rating))\n const topThreeReviews = city.results.slice(0, 3).map(r => numberFrom(r.reviewCount)).filter((v): v is number => v !== null)\n const categories = new Map<string, number>()\n for (const result of city.results) {\n if (!result.category) continue\n categories.set(result.category, (categories.get(result.category) ?? 0) + 1)\n }\n const medReviews = median(resultReviewCounts)\n const medRating = median(resultRatings)\n const topThreeAvg = topThreeReviews.length ? Math.round(topThreeReviews.reduce((a, b) => a + b, 0) / topThreeReviews.length) : null\n const difficulty = Math.min(100, Math.round((topThreeAvg ?? 0) / 20 + (medRating ?? 0) * 10 + city.results.filter(r => r.websiteUrl).length))\n const opportunity = Math.max(0, 100 - difficulty)\n return {\n city: city.city,\n state: city.state,\n population: city.population,\n result_count: city.resultCount,\n median_review_count: medReviews ?? '',\n median_rating: medRating ?? '',\n top_three_average_review_count: topThreeAvg ?? '',\n top_categories: [...categories.entries()].sort((a, b) => b[1] - a[1]).slice(0, 5).map(([cat, count]) => `${cat} (${count})`).join('; '),\n opportunity_score: opportunity,\n difficulty_score: difficulty,\n }\n })\n\n await ctx.artifacts.writeCsv('Competitors CSV', 'competitors.csv', ['city', 'state', 'source_location', 'result_position', 'business_name', 'category', 'review_stars', 'review_count', 'phone', 'website_url', 'place_url', 'cid', 'cid_decimal', 'hydrated', 'reviews_status', 'review_topics', 'owner_response_rate', 'error'], competitorRows)\n await ctx.artifacts.writeCsv('Review insights CSV', 'review-insights.csv', ['city', 'business_name', 'cid', 'review_count', 'average_rating', 'topics', 'praise_terms', 'complaint_terms', 'positive_sample', 'negative_sample'], reviewInsightRows)\n await ctx.artifacts.writeCsv('City summary CSV', 'city-summary.csv', ['city', 'state', 'population', 'result_count', 'median_review_count', 'median_rating', 'top_three_average_review_count', 'top_categories', 'opportunity_score', 'difficulty_score'], citySummaryRows)\n await ctx.artifacts.writeJson('Audit evidence', 'evidence.json', { input, directory, hydrated, citySummaryRows, competitorRows, reviewInsightRows })\n await ctx.artifacts.writeText('Agent tasks', 'tasks.md', [\n '# Local Competitive Audit Tasks',\n '',\n '- [ ] Review city opportunity and difficulty scores as heuristics, not absolute truth.',\n '- [ ] Use review topics and samples as customer-language evidence.',\n '- [ ] Compare target GBP category, review count, and website quality against top competitors.',\n '- [ ] Identify cities with low review-count leaders and weak website coverage.',\n ].join('\\n'))\n\n const summary = `${directory.selectedCityCount} cities, ${directory.totalResultCount} Maps results, ${hydrated.filter(h => h.detail).length} hydrated profiles.`\n await ctx.artifacts.writeText('Summary', 'summary.md', `# Local Competitive Audit\\n\\n${summary}\\n`)\n const reportPath = await ctx.artifacts.writeHtml('HTML report', 'report.html', renderWorkflowReport({\n title: 'Local Competitive Audit',\n subtitle: `${input.query} · ${input.state}`,\n summary,\n warnings,\n tables: [\n { title: 'City Opportunity', columns: ['city', 'state', 'population', 'result_count', 'median_review_count', 'median_rating', 'top_three_average_review_count', 'top_categories', 'opportunity_score', 'difficulty_score'], rows: citySummaryRows },\n { title: 'Hydrated Competitors', columns: ['city', 'result_position', 'business_name', 'category', 'review_stars', 'review_count', 'hydrated', 'review_topics'], rows: competitorRows.slice(0, 100) },\n { title: 'Review Insights', columns: ['city', 'business_name', 'topics', 'praise_terms', 'complaint_terms'], rows: reviewInsightRows.slice(0, 100) },\n ],\n }))\n\n const status = warnings.length || directory.cities.some(city => city.status === 'failed') ? 'partial' : 'succeeded'\n const counts = { cities: directory.selectedCityCount, mapsResults: directory.totalResultCount, hydratedProfiles: hydrated.filter(h => h.detail).length }\n await ctx.artifacts.writeManifest(status, counts, warnings, errors)\n return { title: 'Local Competitive Audit', summary, status, counts, warnings, errors, reportPath }\n },\n}\n","import { z } from 'zod'\nimport { renderWorkflowReport } from '../report-renderer.js'\nimport type { WorkflowDefinition, WorkflowRunContext, WorkflowRunSummary } from '../types.js'\nimport { DIRECTORY_CSV_HEADERS, directoryRows, type DirectoryWorkflowApiResult } from './directory.js'\nimport {\n classifySentence,\n domainFromUrl,\n mapLimit,\n median,\n normalizeDomain,\n numberFrom,\n pageSummaryRow,\n questionRows,\n sourceDomainRows,\n splitSentences,\n textTerms,\n type ExtractUrlResult,\n type HarvestLike,\n type MapsSearchBusinessLike,\n type MapsSearchResultLike,\n type OrganicResult,\n} from './seo-workflow-utils.js'\nimport { DEFAULT_MAPS_PROXY_MODE } from '../../schemas.js'\n\nconst ProxyModeSchema = z.enum(['location', 'configured', 'none'])\n\nconst MapComparisonInputSchema = z.object({\n query: z.string().min(1),\n location: z.string().optional(),\n state: z.string().optional(),\n minPopulation: z.number().int().min(0).default(100_000),\n maxCities: z.number().int().min(1).max(100).default(5),\n maxResultsPerCity: z.number().int().min(1).max(50).default(20),\n hydrateTop: z.number().int().min(0).max(10).default(5),\n maxReviews: z.number().int().min(0).max(500).default(25),\n concurrency: z.number().int().min(1).max(5).default(5),\n proxyMode: ProxyModeSchema.default(DEFAULT_MAPS_PROXY_MODE),\n returnPartial: z.boolean().default(true),\n}).refine(input => input.location || input.state, {\n message: 'Either location or state is required for map-comparison',\n})\n\nconst SerpComparisonInputSchema = z.object({\n keyword: z.string().min(1),\n domain: z.string().optional(),\n url: z.string().url().optional(),\n location: z.string().optional(),\n maxResults: z.number().int().min(1).max(20).default(10),\n maxQuestions: z.number().int().min(1).max(200).default(40),\n extractTop: z.number().int().min(0).max(10).default(5),\n includePaa: z.boolean().default(true),\n includeAiOverview: z.boolean().default(true),\n returnPartial: z.boolean().default(true),\n})\n\nconst PaaExpansionBriefInputSchema = z.object({\n keyword: z.string().min(1),\n location: z.string().optional(),\n maxQuestions: z.number().int().min(1).max(300).default(80),\n depth: z.number().int().min(1).max(6).default(3),\n returnPartial: z.boolean().default(true),\n})\n\nconst AiOverviewLanguageInputSchema = z.object({\n keyword: z.string().min(1),\n domain: z.string().optional(),\n url: z.string().url().optional(),\n location: z.string().optional(),\n maxQuestions: z.number().int().min(1).max(200).default(40),\n extractTop: z.number().int().min(0).max(8).default(3),\n returnPartial: z.boolean().default(true),\n})\n\ntype MapComparisonInput = z.infer<typeof MapComparisonInputSchema>\ntype SerpComparisonInput = z.infer<typeof SerpComparisonInputSchema>\ntype PaaExpansionBriefInput = z.infer<typeof PaaExpansionBriefInputSchema>\ntype AiOverviewLanguageInput = z.infer<typeof AiOverviewLanguageInputSchema>\n\ninterface MapsPlaceIntelResult {\n name?: string | null\n rating?: string | null\n reviewCount?: string | null\n category?: string | null\n website?: string | null\n reviewsStatus?: string\n reviewTopics?: Array<{ label: string; count: string }>\n aboutAttributes?: Array<{ section: string; attribute: string }>\n reviews?: Array<{ stars: string | null; text: string | null; ownerResponse: string | null }>\n}\n\nfunction businessRowsFromMaps(location: string, query: string, results: MapsSearchBusinessLike[]): Array<Record<string, unknown>> {\n return results.map(result => ({\n source_query: query,\n source_location: location,\n city: location.split(',')[0]?.trim() ?? location,\n state: location.split(',')[1]?.trim() ?? '',\n population: '',\n result_position: result.position,\n business_name: result.name,\n review_stars: result.rating ?? '',\n review_count: result.reviewCount ?? '',\n category: result.category ?? '',\n address: result.address ?? '',\n phone: result.phone ?? '',\n website_url: result.websiteUrl ?? '',\n place_url: result.placeUrl ?? '',\n cid: result.cid ?? '',\n cid_decimal: result.cidDecimal ?? '',\n result_status: 'ok',\n error: '',\n }))\n}\n\nfunction marketRows(rows: Array<Record<string, unknown>>): Array<Record<string, unknown>> {\n const byLocation = new Map<string, Array<Record<string, unknown>>>()\n for (const row of rows) {\n const key = String(row.source_location ?? row.location ?? '')\n if (!key) continue\n const list = byLocation.get(key) ?? []\n list.push(row)\n byLocation.set(key, list)\n }\n return [...byLocation.entries()].map(([location, list]) => {\n const counts = list.map(row => numberFrom(row.review_count))\n const ratings = list.map(row => numberFrom(row.review_stars))\n const topThree = list.slice(0, 3).map(row => numberFrom(row.review_count)).filter((v): v is number => v !== null)\n const categories = new Map<string, number>()\n for (const row of list) {\n const category = String(row.category ?? '')\n if (category) categories.set(category, (categories.get(category) ?? 0) + 1)\n }\n return {\n source_location: location,\n result_count: list.filter(row => row.business_name).length,\n median_review_count: median(counts) ?? '',\n median_rating: median(ratings) ?? '',\n top_three_average_review_count: topThree.length ? Math.round(topThree.reduce((a, b) => a + b, 0) / topThree.length) : '',\n top_categories: [...categories.entries()].sort((a, b) => b[1] - a[1]).slice(0, 5).map(([cat, count]) => `${cat} (${count})`).join('; '),\n websites_present: list.filter(row => row.website_url).length,\n }\n })\n}\n\nfunction comparisonRows(rows: Array<Record<string, unknown>>): Array<Record<string, unknown>> {\n const benchmarkByLocation = new Map<string, number>()\n for (const market of marketRows(rows)) {\n benchmarkByLocation.set(String(market.source_location), numberFrom(market.top_three_average_review_count) ?? 0)\n }\n return rows\n .filter(row => row.business_name)\n .map(row => {\n const reviews = numberFrom(row.review_count) ?? 0\n const benchmark = benchmarkByLocation.get(String(row.source_location)) ?? 0\n const websiteMissing = !row.website_url\n const rank = numberFrom(row.result_position) ?? 999\n return {\n source_location: row.source_location,\n result_position: row.result_position,\n business_name: row.business_name,\n category: row.category,\n review_stars: row.review_stars,\n review_count: row.review_count,\n review_gap_to_top3_average: benchmark ? Math.max(0, benchmark - reviews) : '',\n website_url: row.website_url,\n place_url: row.place_url,\n comparison_note: rank <= 3 ? 'visible leader' : websiteMissing ? 'ranking without website' : reviews < benchmark ? 'review-light competitor' : 'visible competitor',\n }\n })\n}\n\nfunction organicRows(serp: HarvestLike | null, targetDomain: string | null): Array<Record<string, unknown>> {\n return (serp?.organicResults ?? []).map(result => {\n const url = result.url ?? ''\n const domain = normalizeDomain(result.domain ?? '') ?? domainFromUrl(url)\n return {\n position: result.position ?? '',\n title: result.title ?? '',\n url,\n domain,\n snippet: result.snippet ?? '',\n is_target: targetDomain ? domain === targetDomain : false,\n }\n })\n}\n\nfunction pageGapRows(targetPage: ExtractUrlResult | null, competitorPages: Array<{ source: OrganicResult; page: ExtractUrlResult }>): Array<Record<string, unknown>> {\n const targetHeadingText = new Set((targetPage?.headings ?? []).map(h => h.text.toLowerCase().replace(/[^a-z0-9\\s]/g, ' ').trim()))\n const targetTerms = new Set((targetPage?.headings ?? []).flatMap(h => h.text.toLowerCase().replace(/[^a-z0-9\\s]/g, ' ').split(/\\s+/).filter(Boolean)))\n const rows: Array<Record<string, unknown>> = []\n for (const { source, page } of competitorPages) {\n for (const heading of page.headings ?? []) {\n if (heading.level > 3 || !heading.text) continue\n const normalized = heading.text.toLowerCase().replace(/[^a-z0-9\\s]/g, ' ').trim()\n const terms = normalized.split(/\\s+/).filter(term => term.length > 3)\n const overlap = terms.filter(term => targetTerms.has(term)).length\n const covered = targetHeadingText.has(normalized) || overlap >= Math.max(2, Math.ceil(terms.length / 2))\n if (covered && targetPage) continue\n rows.push({\n source_position: source.position ?? '',\n source_domain: normalizeDomain(source.domain ?? '') ?? domainFromUrl(source.url),\n source_url: source.url ?? '',\n heading_level: heading.level,\n competitor_heading: heading.text,\n target_coverage: targetPage ? 'not found in target headings' : 'no target page extracted',\n terms: textTerms(heading.text, 6),\n })\n }\n }\n return rows.slice(0, 150)\n}\n\nasync function extractPages(ctx: WorkflowRunContext, sources: OrganicResult[], warnings: string[], labelPrefix: string): Promise<Array<{ source: OrganicResult; page: ExtractUrlResult }>> {\n return mapLimit(sources.filter(source => source.url), 2, async (source, index) => {\n try {\n const page = await ctx.client.post<ExtractUrlResult>('/extract-url', { url: source.url }, 180_000)\n await ctx.artifacts.writeJson(`${labelPrefix} ${index + 1}`, `raw/extract-url/${labelPrefix.toLowerCase()}-${index + 1}.json`, page)\n return { source, page }\n } catch (err) {\n warnings.push(`Page extraction failed for ${source.url}: ${err instanceof Error ? err.message : String(err)}`)\n return null\n }\n }).then(items => items.filter((item): item is { source: OrganicResult; page: ExtractUrlResult } => item !== null))\n}\n\nexport const mapComparisonWorkflowDefinition: WorkflowDefinition<MapComparisonInput> = {\n id: 'map-comparison',\n title: 'Maps Comparison',\n description: 'Compare Google Maps competitors by rank, reviews, stars, categories, websites, and profile/review signals.',\n inputSchema: MapComparisonInputSchema,\n async run(input: MapComparisonInput, ctx: WorkflowRunContext): Promise<WorkflowRunSummary> {\n await ctx.artifacts.writeManifest('running', {}, [], [])\n const warnings: string[] = []\n let rows: Array<Record<string, unknown>>\n let directory: DirectoryWorkflowApiResult | null = null\n let mapsSearch: MapsSearchResultLike | null = null\n\n if (input.location) {\n mapsSearch = await ctx.client.post<MapsSearchResultLike>('/maps/search', {\n query: input.query,\n location: input.location,\n maxResults: input.maxResultsPerCity,\n proxyMode: input.proxyMode,\n }, 240_000)\n rows = businessRowsFromMaps(input.location, input.query, mapsSearch.results)\n await ctx.artifacts.writeJson('Maps search raw JSON', 'raw/maps-search.json', mapsSearch)\n } else {\n directory = await ctx.client.post<DirectoryWorkflowApiResult>('/directory/run', {\n query: input.query,\n state: input.state,\n minPopulation: input.minPopulation,\n maxCities: input.maxCities,\n maxResultsPerCity: input.maxResultsPerCity,\n concurrency: input.concurrency,\n proxyMode: input.proxyMode,\n saveCsv: true,\n }, 900_000)\n rows = directoryRows(directory)\n await ctx.artifacts.writeJson('Directory raw JSON', 'raw/directory-workflow.json', directory)\n await ctx.artifacts.writeCsv('Directory CSV', 'exports/directory.csv', DIRECTORY_CSV_HEADERS, rows)\n warnings.push(...directory.warnings)\n }\n\n const compareRows = comparisonRows(rows)\n const selected = compareRows.slice(0, input.hydrateTop * Math.max(1, input.location ? 1 : input.maxCities))\n const hydrated = await mapLimit(selected, 3, async (row, index) => {\n try {\n const detail = await ctx.client.post<MapsPlaceIntelResult>('/maps/place', {\n businessName: row.business_name,\n location: row.source_location,\n includeReviews: input.maxReviews > 0,\n maxReviews: Math.max(1, input.maxReviews),\n }, 180_000)\n await ctx.artifacts.writeJson(`${row.business_name} profile`, `raw/maps-place-intel/${index + 1}-${String(row.business_name).toLowerCase().replace(/[^a-z0-9]+/g, '-')}.json`, detail)\n return { row, detail, error: '' }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n warnings.push(`Profile hydration failed for ${row.business_name}: ${message}`)\n return { row, detail: null, error: message }\n }\n })\n\n const profileRows = hydrated.map(({ row, detail, error }) => ({\n source_location: row.source_location,\n result_position: row.result_position,\n business_name: row.business_name,\n category: detail?.category ?? row.category,\n review_stars: detail?.rating ?? row.review_stars,\n review_count: detail?.reviewCount ?? row.review_count,\n website_url: detail?.website ?? row.website_url,\n review_topics: (detail?.reviewTopics ?? []).map(t => `${t.label} (${t.count})`).join('; '),\n about_attributes: (detail?.aboutAttributes ?? []).map(a => `${a.section}: ${a.attribute}`).join('; '),\n reviews_status: detail?.reviewsStatus ?? '',\n error,\n }))\n const markets = marketRows(rows)\n await ctx.artifacts.writeCsv('Maps results CSV', 'maps-results.csv', ['source_query', 'source_location', 'city', 'state', 'population', 'result_position', 'business_name', 'review_stars', 'review_count', 'category', 'address', 'phone', 'website_url', 'place_url', 'cid', 'cid_decimal', 'result_status', 'error'], rows)\n await ctx.artifacts.writeCsv('Comparison CSV', 'map-comparison.csv', ['source_location', 'result_position', 'business_name', 'category', 'review_stars', 'review_count', 'review_gap_to_top3_average', 'website_url', 'place_url', 'comparison_note'], compareRows)\n await ctx.artifacts.writeCsv('Profile insights CSV', 'profile-insights.csv', ['source_location', 'result_position', 'business_name', 'category', 'review_stars', 'review_count', 'website_url', 'review_topics', 'about_attributes', 'reviews_status', 'error'], profileRows)\n await ctx.artifacts.writeJson('Maps comparison evidence', 'evidence.json', { input, directory, mapsSearch, rows, compareRows, profileRows, markets, warnings })\n await ctx.artifacts.writeText('Brief', 'brief.md', [\n `# Maps Comparison: ${input.query}`,\n '',\n `Markets: ${markets.map(row => row.source_location).join(', ')}`,\n '',\n '## How to Use',\n '- Compare rank position against review count and category patterns.',\n '- Treat review gaps and missing websites as opportunity signals, not guarantees.',\n '- Use profile topics and attributes as evidence for local content and GBP improvements.',\n ].join('\\n'))\n\n const summary = `${compareRows.length} Maps competitors compared across ${markets.length} market(s); ${profileRows.filter(row => !row.error).length} profiles hydrated.`\n const reportPath = await ctx.artifacts.writeHtml('HTML report', 'report.html', renderWorkflowReport({\n title: 'Maps Comparison',\n subtitle: `${input.query}${input.location ? ` · ${input.location}` : input.state ? ` · ${input.state}` : ''}`,\n summary,\n warnings,\n tables: [\n { title: 'Market Benchmarks', columns: ['source_location', 'result_count', 'median_review_count', 'median_rating', 'top_three_average_review_count', 'top_categories', 'websites_present'], rows: markets },\n { title: 'Competitor Comparison', columns: ['source_location', 'result_position', 'business_name', 'category', 'review_stars', 'review_count', 'review_gap_to_top3_average', 'comparison_note'], rows: compareRows.slice(0, 120) },\n { title: 'Profile Insights', columns: ['source_location', 'business_name', 'review_topics', 'about_attributes', 'error'], rows: profileRows },\n ],\n }))\n const status = warnings.length ? 'partial' : 'succeeded'\n const counts = { markets: markets.length, competitors: compareRows.length, hydratedProfiles: profileRows.filter(row => !row.error).length }\n await ctx.artifacts.writeManifest(status, counts, warnings, [])\n return { title: 'Maps Comparison', summary, status, counts, warnings, errors: [], reportPath }\n },\n}\n\nexport const serpComparisonWorkflowDefinition: WorkflowDefinition<SerpComparisonInput> = {\n id: 'serp-comparison',\n title: 'SERP Comparison',\n description: 'Compare ranking pages, SERP features, PAA evidence, AI Overview citations, and page-level content gaps.',\n inputSchema: SerpComparisonInputSchema,\n async run(input: SerpComparisonInput, ctx: WorkflowRunContext): Promise<WorkflowRunSummary> {\n await ctx.artifacts.writeManifest('running', {}, [], [])\n const warnings: string[] = []\n const targetDomain = normalizeDomain(input.domain ?? input.url ?? null)\n const serp = await ctx.client.post<HarvestLike>('/harvest/sync', {\n query: input.keyword,\n location: input.location,\n serpOnly: true,\n maxQuestions: 1,\n format: 'json',\n }, 180_000)\n await ctx.artifacts.writeJson('SERP raw JSON', 'raw/serp.json', serp)\n\n let paa: HarvestLike | null = null\n if (input.includePaa) {\n try {\n paa = await ctx.client.post<HarvestLike>('/harvest/sync', {\n query: input.keyword,\n location: input.location,\n maxQuestions: input.maxQuestions,\n format: 'json',\n }, 280_000)\n await ctx.artifacts.writeJson('PAA raw JSON', 'raw/paa.json', paa)\n } catch (err) {\n warnings.push(`PAA evidence unavailable: ${err instanceof Error ? err.message : String(err)}`)\n }\n }\n\n const organic = organicRows(serp, targetDomain).slice(0, input.maxResults)\n const organicSources = (serp.organicResults ?? []).slice(0, input.maxResults)\n const targetSource = input.url\n ? { position: 0, title: 'Target page', url: input.url, domain: domainFromUrl(input.url) }\n : organicSources.find(result => targetDomain && (normalizeDomain(result.domain ?? '') ?? domainFromUrl(result.url)) === targetDomain)\n const competitorSources = organicSources\n .filter(result => result.url && result.url !== targetSource?.url)\n .filter(result => !targetDomain || (normalizeDomain(result.domain ?? '') ?? domainFromUrl(result.url)) !== targetDomain)\n .slice(0, input.extractTop)\n\n const targetPages = targetSource ? await extractPages(ctx, [targetSource], warnings, 'Target') : []\n const competitorPages = input.extractTop > 0 ? await extractPages(ctx, competitorSources, warnings, 'Competitor') : []\n const targetPage = targetPages[0]?.page ?? null\n const pageRows = [\n ...targetPages.map(({ source, page }) => pageSummaryRow(page, { url: source.url ?? '', domain: normalizeDomain(source.domain ?? '') ?? domainFromUrl(source.url), position: source.position, title: source.title })),\n ...competitorPages.map(({ source, page }) => pageSummaryRow(page, { url: source.url ?? '', domain: normalizeDomain(source.domain ?? '') ?? domainFromUrl(source.url), position: source.position, title: source.title })),\n ]\n const gaps = pageGapRows(targetPage, competitorPages)\n const questions = questionRows(paa)\n const aiRows = (serp.aiOverview?.citations ?? []).map((citation, index) => ({\n citation_position: index + 1,\n citation_text: citation.text ?? '',\n url: citation.href ?? '',\n domain: domainFromUrl(citation.href ?? ''),\n is_target: targetDomain ? domainFromUrl(citation.href ?? '') === targetDomain : false,\n }))\n await ctx.artifacts.writeCsv('Organic results CSV', 'organic-results.csv', ['position', 'title', 'url', 'domain', 'snippet', 'is_target'], organic)\n await ctx.artifacts.writeCsv('Page comparison CSV', 'page-comparison.csv', ['position', 'domain', 'url', 'serp_title', 'page_title', 'h1', 'meta_description', 'word_count', 'heading_count', 'schema_types'], pageRows)\n await ctx.artifacts.writeCsv('Content gaps CSV', 'content-gaps.csv', ['source_position', 'source_domain', 'source_url', 'heading_level', 'competitor_heading', 'target_coverage', 'terms'], gaps)\n await ctx.artifacts.writeCsv('PAA questions CSV', 'paa-questions.csv', ['position', 'intent', 'question', 'answer_excerpt', 'source_title', 'source_domain', 'source_url'], questions)\n await ctx.artifacts.writeCsv('AI Overview citations CSV', 'ai-overview-citations.csv', ['citation_position', 'citation_text', 'url', 'domain', 'is_target'], aiRows)\n await ctx.artifacts.writeJson('SERP comparison evidence', 'evidence.json', { input, serp, paa, organic, pageRows, gaps, questions, aiRows, warnings })\n await ctx.artifacts.writeText('Writer brief', 'brief.md', [\n `# SERP Comparison Brief: ${input.keyword}`,\n '',\n `Target: ${targetDomain ?? input.url ?? 'not specified'}`,\n `Location: ${input.location ?? 'not specified'}`,\n '',\n '## Recommended Actions',\n '- Use `content-gaps.csv` to decide which missing sections deserve coverage.',\n '- Use `paa-questions.csv` for FAQ and answer-block candidates.',\n '- Use `ai-overview-citations.csv` to see whether the target is cited in AI Overview evidence.',\n '- Treat extracted page headings as evidence, not a complete semantic analysis.',\n ].join('\\n'))\n const summary = `${organic.length} organic results, ${pageRows.length} extracted pages, ${gaps.length} heading gaps, ${questions.length} PAA questions.`\n const reportPath = await ctx.artifacts.writeHtml('HTML report', 'report.html', renderWorkflowReport({\n title: 'SERP Comparison',\n subtitle: `${input.keyword}${input.location ? ` · ${input.location}` : ''}`,\n summary,\n warnings,\n tables: [\n { title: 'Organic Results', columns: ['position', 'title', 'domain', 'is_target'], rows: organic },\n { title: 'Page Comparison', columns: ['position', 'domain', 'h1', 'word_count', 'heading_count', 'schema_types'], rows: pageRows },\n { title: 'Content Gaps', columns: ['source_position', 'source_domain', 'competitor_heading', 'target_coverage', 'terms'], rows: gaps.slice(0, 80) },\n { title: 'PAA Questions', columns: ['position', 'intent', 'question', 'source_domain'], rows: questions.slice(0, 80) },\n ],\n }))\n const status = warnings.length ? 'partial' : 'succeeded'\n const counts = { organic: organic.length, pages: pageRows.length, gaps: gaps.length, questions: questions.length, aiCitations: aiRows.length }\n await ctx.artifacts.writeManifest(status, counts, warnings, [])\n return { title: 'SERP Comparison', summary, status, counts, warnings, errors: [], reportPath }\n },\n}\n\nexport const paaExpansionBriefWorkflowDefinition: WorkflowDefinition<PaaExpansionBriefInput> = {\n id: 'paa-expansion-brief',\n title: 'PAA Expansion Brief',\n description: 'Expand People Also Ask questions into an evidence-backed writer brief, section map, and source table.',\n inputSchema: PaaExpansionBriefInputSchema,\n async run(input: PaaExpansionBriefInput, ctx: WorkflowRunContext): Promise<WorkflowRunSummary> {\n await ctx.artifacts.writeManifest('running', {}, [], [])\n const warnings: string[] = []\n const paa = await ctx.client.post<HarvestLike>('/harvest/sync', {\n query: input.keyword,\n location: input.location,\n maxQuestions: input.maxQuestions,\n depth: input.depth,\n format: 'json',\n }, 300_000)\n await ctx.artifacts.writeJson('PAA raw JSON', 'raw/paa.json', paa)\n const questions = questionRows(paa)\n const sourceRows = sourceDomainRows(questions)\n const byIntent = new Map<string, Array<Record<string, unknown>>>()\n for (const row of questions) {\n const list = byIntent.get(String(row.intent)) ?? []\n list.push(row)\n byIntent.set(String(row.intent), list)\n }\n const sectionRows = [...byIntent.entries()].map(([intent, rows]) => ({\n recommended_section: intent,\n question_count: rows.length,\n sample_questions: rows.slice(0, 5).map(row => row.question).join(' | '),\n source_domains: [...new Set(rows.map(row => row.source_domain).filter(Boolean))].slice(0, 5).join('; '),\n terms: textTerms(rows.map(row => `${row.question} ${row.answer_excerpt}`).join(' '), 10),\n })).sort((a, b) => Number(b.question_count) - Number(a.question_count))\n\n await ctx.artifacts.writeCsv('PAA questions CSV', 'paa-questions.csv', ['position', 'intent', 'question', 'answer_excerpt', 'source_title', 'source_domain', 'source_url'], questions)\n await ctx.artifacts.writeCsv('Source domains CSV', 'source-domains.csv', ['domain', 'question_mentions', 'source_url_count', 'top_intents'], sourceRows)\n await ctx.artifacts.writeCsv('Section map CSV', 'section-map.csv', ['recommended_section', 'question_count', 'sample_questions', 'source_domains', 'terms'], sectionRows)\n await ctx.artifacts.writeJson('PAA brief evidence', 'evidence.json', { input, paa, questions, sourceRows, sectionRows })\n await ctx.artifacts.writeText('Writer brief', 'writer-brief.md', [\n `# PAA Expansion Brief: ${input.keyword}`,\n '',\n `Location: ${input.location ?? 'not specified'}`,\n '',\n '## Suggested Page Structure',\n ...sectionRows.map(row => `- ${row.recommended_section}: answer ${row.question_count} related question(s). Sample: ${row.sample_questions}`),\n '',\n '## Writing Rules',\n '- Answer the highest-frequency question in the first 60 words of each section.',\n '- Use exact customer question language from `paa-questions.csv` for H2/H3 candidates.',\n '- Use `source-domains.csv` to identify which source types Google is already rewarding.',\n '- Do not invent citations; cite only rows that have a source URL.',\n ].join('\\n'))\n const summary = `${questions.length} PAA questions grouped into ${sectionRows.length} writing sections.`\n const reportPath = await ctx.artifacts.writeHtml('HTML report', 'report.html', renderWorkflowReport({\n title: 'PAA Expansion Brief',\n subtitle: `${input.keyword}${input.location ? ` · ${input.location}` : ''}`,\n summary,\n warnings,\n tables: [\n { title: 'Section Map', columns: ['recommended_section', 'question_count', 'sample_questions', 'source_domains', 'terms'], rows: sectionRows },\n { title: 'Questions', columns: ['position', 'intent', 'question', 'source_domain'], rows: questions.slice(0, 120) },\n { title: 'Source Domains', columns: ['domain', 'question_mentions', 'source_url_count', 'top_intents'], rows: sourceRows },\n ],\n }))\n const counts = { questions: questions.length, sections: sectionRows.length, sourceDomains: sourceRows.length }\n await ctx.artifacts.writeManifest('succeeded', counts, warnings, [])\n return { title: 'PAA Expansion Brief', summary, status: 'succeeded', counts, warnings, errors: [], reportPath }\n },\n}\n\nexport const aiOverviewLanguageWorkflowDefinition: WorkflowDefinition<AiOverviewLanguageInput> = {\n id: 'ai-overview-language',\n title: 'AI Overview Language Brief',\n description: 'Turn AI Overview, citation, PAA, and ranking-page evidence into answer-block and citation-hook guidance.',\n inputSchema: AiOverviewLanguageInputSchema,\n async run(input: AiOverviewLanguageInput, ctx: WorkflowRunContext): Promise<WorkflowRunSummary> {\n await ctx.artifacts.writeManifest('running', {}, [], [])\n const warnings: string[] = []\n const targetDomain = normalizeDomain(input.domain ?? input.url ?? null)\n const serp = await ctx.client.post<HarvestLike>('/harvest/sync', {\n query: input.keyword,\n location: input.location,\n serpOnly: true,\n maxQuestions: 1,\n format: 'json',\n }, 180_000)\n await ctx.artifacts.writeJson('SERP raw JSON', 'raw/serp.json', serp)\n let paa: HarvestLike | null = null\n try {\n paa = await ctx.client.post<HarvestLike>('/harvest/sync', {\n query: input.keyword,\n location: input.location,\n maxQuestions: input.maxQuestions,\n format: 'json',\n }, 280_000)\n await ctx.artifacts.writeJson('PAA raw JSON', 'raw/paa.json', paa)\n } catch (err) {\n warnings.push(`PAA evidence unavailable: ${err instanceof Error ? err.message : String(err)}`)\n }\n\n const citations = (serp.aiOverview?.citations ?? []).map((citation, index) => {\n const domain = domainFromUrl(citation.href ?? '')\n return {\n citation_position: index + 1,\n citation_text: citation.text ?? '',\n url: citation.href ?? '',\n domain,\n is_target: targetDomain ? domain === targetDomain : false,\n }\n })\n const aioSentences = splitSentences(serp.aiOverview?.text)\n const claimRows = aioSentences.map((sentence, index) => ({\n position: index + 1,\n claim_type: classifySentence(sentence),\n sentence,\n reusable_pattern: sentence.length > 140 ? `${sentence.slice(0, 140)}...` : sentence,\n }))\n const questions = questionRows(paa)\n const citationSources = (serp.aiOverview?.citations ?? [])\n .filter(citation => citation.href)\n .map((citation, index) => ({ position: index + 1, title: citation.text, url: citation.href, domain: domainFromUrl(citation.href) }))\n .slice(0, input.extractTop)\n const extractedCitations = input.extractTop > 0 ? await extractPages(ctx, citationSources, warnings, 'Citation') : []\n const extractedRows = extractedCitations.map(({ source, page }) => pageSummaryRow(page, { url: source.url ?? '', domain: normalizeDomain(source.domain ?? '') ?? domainFromUrl(source.url), position: source.position, title: source.title }))\n const languageRows = [\n {\n block: 'direct_answer',\n guidance: 'Open with a 40-70 word answer that directly resolves the query before adding context.',\n evidence_basis: questions[0]?.question ?? input.keyword,\n },\n {\n block: 'criteria_or_steps',\n guidance: 'List the criteria, steps, or decision factors Google is already compressing into AI Overview language.',\n evidence_basis: claimRows.filter(row => ['criteria', 'process'].includes(String(row.claim_type))).map(row => row.sentence).slice(0, 3).join(' | '),\n },\n {\n block: 'citation_hook',\n guidance: 'Add source-worthy details competitors can cite: definitions, numbers, examples, process details, and named entity relationships.',\n evidence_basis: citations.map(row => `${row.domain}: ${row.citation_text}`).slice(0, 5).join(' | '),\n },\n {\n block: 'faq_followups',\n guidance: 'Use PAA phrasing for follow-up sections so the page answers adjacent questions in Google language.',\n evidence_basis: questions.slice(0, 5).map(row => row.question).join(' | '),\n },\n ]\n await ctx.artifacts.writeCsv('AI Overview citations CSV', 'ai-overview-citations.csv', ['citation_position', 'citation_text', 'url', 'domain', 'is_target'], citations)\n await ctx.artifacts.writeCsv('AI Overview claim patterns CSV', 'claim-patterns.csv', ['position', 'claim_type', 'sentence', 'reusable_pattern'], claimRows)\n await ctx.artifacts.writeCsv('Language guidance CSV', 'language-guidance.csv', ['block', 'guidance', 'evidence_basis'], languageRows)\n await ctx.artifacts.writeCsv('PAA questions CSV', 'paa-questions.csv', ['position', 'intent', 'question', 'answer_excerpt', 'source_title', 'source_domain', 'source_url'], questions)\n await ctx.artifacts.writeCsv('Extracted citation pages CSV', 'citation-pages.csv', ['position', 'domain', 'url', 'serp_title', 'page_title', 'h1', 'meta_description', 'word_count', 'heading_count', 'schema_types'], extractedRows)\n await ctx.artifacts.writeJson('AI Overview language evidence', 'evidence.json', { input, serp, paa, citations, claimRows, languageRows, extractedRows, warnings })\n await ctx.artifacts.writeText('Answer block template', 'answer-block-template.md', [\n `# AI Overview Language Brief: ${input.keyword}`,\n '',\n `AI Overview detected: ${serp.aiOverview?.detected ? 'yes' : 'no'}`,\n `Target cited: ${targetDomain ? citations.some(row => row.is_target) ? 'yes' : 'no' : 'target not specified'}`,\n '',\n '## Direct Answer Block',\n 'Write one compact answer block that starts with the answer, not background. Keep it clear enough that Google could lift it as a standalone summary.',\n '',\n '## Suggested Follow-Up Blocks',\n ...languageRows.map(row => `- ${row.block}: ${row.guidance}`),\n '',\n '## Evidence to Mirror',\n ...claimRows.slice(0, 8).map(row => `- ${row.claim_type}: ${row.sentence}`),\n '',\n '## Citation Hooks',\n ...citations.slice(0, 8).map(row => `- ${row.domain}: ${row.citation_text}`),\n ].join('\\n'))\n const summary = `${citations.length} AI Overview citations, ${claimRows.length} claim patterns, ${questions.length} PAA questions, ${extractedRows.length} citation pages extracted.`\n const reportPath = await ctx.artifacts.writeHtml('HTML report', 'report.html', renderWorkflowReport({\n title: 'AI Overview Language Brief',\n subtitle: `${input.keyword}${input.location ? ` · ${input.location}` : ''}`,\n summary,\n warnings,\n tables: [\n { title: 'Language Guidance', columns: ['block', 'guidance', 'evidence_basis'], rows: languageRows },\n { title: 'AI Overview Citations', columns: ['citation_position', 'citation_text', 'domain', 'is_target'], rows: citations },\n { title: 'Claim Patterns', columns: ['position', 'claim_type', 'sentence'], rows: claimRows },\n { title: 'PAA Follow-Ups', columns: ['position', 'intent', 'question', 'source_domain'], rows: questions.slice(0, 60) },\n ],\n }))\n const status = warnings.length || !serp.aiOverview?.detected ? 'partial' : 'succeeded'\n const counts = { citations: citations.length, claimPatterns: claimRows.length, questions: questions.length, extractedCitationPages: extractedRows.length }\n await ctx.artifacts.writeManifest(status, counts, warnings, [])\n return { title: 'AI Overview Language Brief', summary, status, counts, warnings, errors: [], reportPath }\n },\n}\n","export interface OrganicResult {\n position?: number\n title?: string\n url?: string\n domain?: string\n snippet?: string | null\n}\n\nexport interface PaaFlatRow {\n question?: string\n answer?: string | null\n source_title?: string | null\n source_site?: string | null\n source_cite?: string | null\n}\n\nexport interface HarvestLike {\n organicResults?: OrganicResult[]\n localPack?: Array<{ position?: number; name?: string; rating?: string | null; reviewCount?: string | null; websiteUrl?: string | null }>\n flat?: PaaFlatRow[]\n aiOverview?: { detected?: boolean; text?: string | null; citations?: Array<{ text?: string; href?: string }> }\n forumResults?: Array<{ title?: string; source?: string; url?: string }>\n videoResults?: Array<{ title?: string; channel?: string; platform?: string; url?: string }>\n}\n\nexport interface ExtractUrlResult {\n url?: string\n canonicalUrl?: string | null\n title?: string | null\n metaDescription?: string | null\n h1?: string | null\n headings?: Array<{ level: number; text: string }>\n wordCount?: number\n schemaTypes?: string[]\n bodyMarkdown?: string\n}\n\nexport interface MapsSearchBusinessLike {\n position: number\n name: string\n rating?: string | null\n reviewCount?: string | null\n category?: string | null\n address?: string | null\n phone?: string | null\n websiteUrl?: string | null\n placeUrl?: string\n cid?: string | null\n cidDecimal?: string | null\n hoursStatus?: string | null\n}\n\nexport interface MapsSearchResultLike {\n query: string\n location?: string | null\n searchQuery?: string\n resultCount: number\n results: MapsSearchBusinessLike[]\n}\n\nconst STOP_WORDS = new Set([\n 'about', 'after', 'also', 'because', 'been', 'best', 'both', 'from', 'have', 'into',\n 'more', 'most', 'near', 'only', 'over', 'than', 'that', 'their', 'them', 'then',\n 'there', 'these', 'they', 'this', 'what', 'when', 'where', 'which', 'while', 'with',\n 'your', 'will', 'would', 'should', 'could', 'does', 'were', 'cost', 'costs',\n])\n\nexport function normalizeDomain(value?: string | null): string | null {\n if (!value) return null\n try {\n const url = new URL(value.includes('://') ? value : `https://${value}`)\n return url.hostname.replace(/^www\\./, '').toLowerCase()\n } catch {\n return value.replace(/^https?:\\/\\//, '').replace(/^www\\./, '').split('/')[0]?.toLowerCase() || null\n }\n}\n\nexport function domainFromUrl(url?: string | null): string {\n return normalizeDomain(url) ?? ''\n}\n\nexport function numberFrom(value: unknown): number | null {\n if (value === null || value === undefined || value === '') return null\n const parsed = Number(String(value).replace(/[^\\d.]/g, ''))\n return Number.isFinite(parsed) ? parsed : null\n}\n\nexport function median(values: Array<number | null>): number | null {\n const nums = values.filter((v): v is number => v !== null).sort((a, b) => a - b)\n if (!nums.length) return null\n return nums[Math.floor(nums.length / 2)] ?? null\n}\n\nexport function textTerms(text: string, limit = 12): string {\n const counts = new Map<string, number>()\n for (const token of text.toLowerCase().replace(/[^a-z0-9\\s]/g, ' ').split(/\\s+/)) {\n if (token.length < 4 || STOP_WORDS.has(token)) continue\n counts.set(token, (counts.get(token) ?? 0) + 1)\n }\n return [...counts.entries()]\n .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))\n .slice(0, limit)\n .map(([term, count]) => `${term} (${count})`)\n .join('; ')\n}\n\nexport function classifyQuestion(question: string): string {\n const q = question.toLowerCase()\n if (/\\b(cost|price|pricing|charge|expensive|cheap)\\b/.test(q)) return 'cost'\n if (/\\b(best|top|recommended|reviews?|compare|versus|vs)\\b/.test(q)) return 'comparison'\n if (/\\b(how|steps?|process|way to)\\b/.test(q)) return 'process'\n if (/\\b(why|worth|important|benefit)\\b/.test(q)) return 'why'\n if (/\\b(near me|city|local|nearby)\\b/.test(q)) return 'local'\n if (/\\b(can|does|do|is|are|should|will)\\b/.test(q)) return 'decision'\n return 'definition'\n}\n\nexport function questionRows(paa: HarvestLike | null): Array<Record<string, unknown>> {\n return (paa?.flat ?? [])\n .filter(row => row.question)\n .map((row, index) => {\n const url = row.source_cite ?? ''\n const domain = normalizeDomain(row.source_site ?? '') ?? domainFromUrl(url)\n return {\n position: index + 1,\n intent: classifyQuestion(row.question ?? ''),\n question: row.question ?? '',\n answer_excerpt: (row.answer ?? '').slice(0, 320),\n source_title: row.source_title ?? '',\n source_domain: domain,\n source_url: url,\n }\n })\n}\n\nexport function sourceDomainRows(rows: Array<Record<string, unknown>>): Array<Record<string, unknown>> {\n const byDomain = new Map<string, { questions: number; urls: Set<string>; intents: Map<string, number> }>()\n for (const row of rows) {\n const domain = String(row.source_domain ?? row.domain ?? '')\n if (!domain) continue\n const entry = byDomain.get(domain) ?? { questions: 0, urls: new Set<string>(), intents: new Map<string, number>() }\n entry.questions += row.question ? 1 : 0\n if (row.source_url || row.url) entry.urls.add(String(row.source_url ?? row.url))\n if (row.intent) entry.intents.set(String(row.intent), (entry.intents.get(String(row.intent)) ?? 0) + 1)\n byDomain.set(domain, entry)\n }\n return [...byDomain.entries()]\n .map(([domain, entry]) => ({\n domain,\n question_mentions: entry.questions,\n source_url_count: entry.urls.size,\n top_intents: [...entry.intents.entries()].sort((a, b) => b[1] - a[1]).map(([intent, count]) => `${intent} (${count})`).join('; '),\n }))\n .sort((a, b) => Number(b.question_mentions) - Number(a.question_mentions) || String(a.domain).localeCompare(String(b.domain)))\n}\n\nexport function splitSentences(text?: string | null): string[] {\n return (text ?? '')\n .replace(/\\s+/g, ' ')\n .split(/(?<=[.!?])\\s+/)\n .map(sentence => sentence.trim())\n .filter(sentence => sentence.length > 20)\n .slice(0, 20)\n}\n\nexport function classifySentence(sentence: string): string {\n const s = sentence.toLowerCase()\n if (/\\bis\\b|\\bare\\b|\\bmeans\\b|\\brefers to\\b/.test(s)) return 'definition'\n if (/\\binclude\\b|\\bconsider\\b|\\bfactors?\\b|\\bcriteria\\b/.test(s)) return 'criteria'\n if (/\\bfirst\\b|\\bthen\\b|\\bsteps?\\b|\\bprocess\\b/.test(s)) return 'process'\n if (/\\bvs\\b|\\bthan\\b|\\bcompare\\b|\\bdifference\\b/.test(s)) return 'comparison'\n if (/\\bcost\\b|\\bprice\\b|\\baverage\\b|\\brange\\b/.test(s)) return 'cost'\n return 'claim'\n}\n\nexport function headingRows(page: ExtractUrlResult, source: { url: string; domain: string; position?: number | string }): Array<Record<string, unknown>> {\n return (page.headings ?? [])\n .filter(heading => heading.text)\n .map(heading => ({\n source_url: source.url,\n source_domain: source.domain,\n source_position: source.position ?? '',\n heading_level: heading.level,\n heading_text: heading.text,\n heading_terms: textTerms(heading.text, 6),\n }))\n}\n\nexport function pageSummaryRow(page: ExtractUrlResult, source: { url: string; domain: string; position?: number | string; title?: string }): Record<string, unknown> {\n return {\n position: source.position ?? '',\n domain: source.domain,\n url: source.url,\n serp_title: source.title ?? '',\n page_title: page.title ?? '',\n h1: page.h1 ?? '',\n meta_description: page.metaDescription ?? '',\n word_count: page.wordCount ?? '',\n heading_count: page.headings?.length ?? 0,\n schema_types: (page.schemaTypes ?? []).join('; '),\n }\n}\n\nexport async function mapLimit<T, R>(items: T[], limit: number, fn: (item: T, index: number) => Promise<R>): Promise<R[]> {\n const out: R[] = new Array(items.length)\n let next = 0\n async function worker(): Promise<void> {\n while (next < items.length) {\n const index = next\n next += 1\n out[index] = await fn(items[index], index)\n }\n }\n await Promise.all(Array.from({ length: Math.min(Math.max(1, limit), items.length) }, () => worker()))\n return out\n}\n\n","#!/usr/bin/env node\nimport { runHumanCli } from '../src/cli/human-cli.js'\n\nrunHumanCli().catch((err) => {\n console.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n})\n\n"],"mappings":"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","names":["import_node_child_process","import_promises","import_node_path","import_promises","import_node_os","import_node_path","status","import_promises","import_zod","status","import_zod","import_zod","status","import_zod","status","import_zod","mapLimit","competitorRows","status","import_zod","normalizeDomain","domainFromUrl","numberFrom","median","mapLimit","numberFrom","median","normalizeDomain","domainFromUrl","mapLimit","status","sourceRows"]}
1
+ {"version":3,"sources":["../../src/cli/human-cli.ts","../../src/version.ts","../../src/cli/agent-config.ts","../../src/cli/doctor.ts","../../src/cli/prompts.ts","../../src/workflows/artifact-writer.ts","../../src/directory/csv.ts","../../src/lib/slugify.ts","../../src/output/memory-library-sink.ts","../../src/workflows/registry.ts","../../src/workflows/http-client.ts","../../src/workflows/workflows/agent-packet.ts","../../src/workflows/report-renderer.ts","../../src/workflows/workflows/directory.ts","../../src/schemas.ts","../../src/workflows/workflows/get-leads.ts","../../src/workflows/workflows/local-competitive-audit.ts","../../src/workflows/workflows/comparison-briefs.ts","../../src/workflows/workflows/seo-workflow-utils.ts","../../bin/mcp-scraper-cli.ts"],"sourcesContent":["import { Command } from 'commander'\nimport { spawn } from 'node:child_process'\nimport { mkdir, writeFile } from 'node:fs/promises'\nimport { basename, join } from 'node:path'\nimport { PACKAGE_VERSION } from '../version.js'\nimport {\n claudeMcpAddArgs,\n claudeMcpRemoveArgs,\n normalizeAgentHost,\n renderAgentInstall,\n type AgentHost,\n} from './agent-config.js'\nimport { renderDoctor, runDoctor } from './doctor.js'\nimport { listPrompts, renderPrompt } from './prompts.js'\nimport { workflowOutputBaseDir } from '../workflows/artifact-writer.js'\nimport { findWorkflowReport, listWorkflowDefinitions, listWorkflowReports, openWorkflowReport, runWorkflow } from '../workflows/registry.js'\n\nfunction numberOpt(value: unknown): number | undefined {\n if (value === undefined || value === null || value === '') return undefined\n const parsed = Number(value)\n return Number.isFinite(parsed) ? parsed : undefined\n}\n\nfunction booleanOpt(value: unknown): boolean | undefined {\n if (value === undefined) return undefined\n if (typeof value === 'boolean') return value\n if (value === 'true') return true\n if (value === 'false') return false\n return undefined\n}\n\nfunction compactInput(input: Record<string, unknown>): Record<string, unknown> {\n return Object.fromEntries(Object.entries(input).filter(([, value]) => value !== undefined))\n}\n\nfunction workflowInput(id: string, opts: Record<string, unknown>): Record<string, unknown> {\n if (id === 'agent-packet' || id === 'serp-comparison' || id === 'ai-overview-language') {\n return compactInput({\n keyword: opts.keyword,\n domain: opts.domain,\n url: opts.url,\n location: opts.location,\n maxResults: numberOpt(opts.maxResults),\n maxQuestions: numberOpt(opts.maxQuestions),\n extractTop: numberOpt(opts.extractTop),\n includeSerp: opts.serp === false ? false : undefined,\n includePaa: opts.paa === false ? false : undefined,\n includeAiOverview: booleanOpt(opts.includeAiOverview),\n returnPartial: opts.returnPartial === false ? false : undefined,\n })\n }\n\n if (id === 'paa-expansion-brief') {\n return compactInput({\n keyword: opts.keyword,\n location: opts.location,\n maxQuestions: numberOpt(opts.maxQuestions),\n depth: numberOpt(opts.depth),\n returnPartial: opts.returnPartial === false ? false : undefined,\n })\n }\n\n if (id === 'directory' || id === 'local-competitive-audit' || id === 'map-comparison') {\n return compactInput({\n query: opts.query,\n location: opts.location,\n state: opts.state,\n minPopulation: numberOpt(opts.minPop ?? opts.minPopulation),\n maxCities: numberOpt(opts.maxCities),\n maxResultsPerCity: numberOpt(opts.perCity ?? opts.maxResultsPerCity ?? opts.maxResults),\n concurrency: numberOpt(opts.concurrency),\n proxyMode: opts.proxyMode,\n hydrateTop: id === 'local-competitive-audit' || id === 'map-comparison' ? numberOpt(opts.hydrateTop) : undefined,\n maxReviews: id === 'local-competitive-audit' || id === 'map-comparison' ? numberOpt(opts.reviews ?? opts.maxReviews) : undefined,\n returnPartial: opts.returnPartial === false ? false : undefined,\n })\n }\n\n return compactInput(opts)\n}\n\nfunction writeOutput(data: unknown, json: boolean | undefined): void {\n if (json) {\n process.stdout.write(`${JSON.stringify(data, null, 2)}\\n`)\n } else if (typeof data === 'string') {\n process.stdout.write(`${data}\\n`)\n } else {\n process.stdout.write(`${JSON.stringify(data, null, 2)}\\n`)\n }\n}\n\nfunction maskSecrets(value: string): string {\n return value.replace(/sk_[A-Za-z0-9_-]+/g, 'sk_***')\n}\n\nfunction runLocalCommand(command: string, args: string[]): Promise<{ code: number; stdout: string; stderr: string }> {\n return new Promise((resolve) => {\n const child = spawn(command, args, { stdio: ['ignore', 'pipe', 'pipe'] })\n const stdout: Buffer[] = []\n const stderr: Buffer[] = []\n let settled = false\n const done = (result: { code: number; stdout: string; stderr: string }) => {\n if (settled) return\n settled = true\n resolve(result)\n }\n child.stdout.on('data', chunk => stdout.push(Buffer.from(chunk)))\n child.stderr.on('data', chunk => stderr.push(Buffer.from(chunk)))\n child.on('error', err => {\n done({ code: 127, stdout: '', stderr: err.message })\n })\n child.on('close', code => {\n done({\n code: typeof code === 'number' ? code : 1,\n stdout: Buffer.concat(stdout).toString('utf8'),\n stderr: Buffer.concat(stderr).toString('utf8'),\n })\n })\n })\n}\n\nfunction cadenceOpt(opts: Record<string, unknown>): 'daily' | 'weekly' | 'monthly' {\n if (opts.daily) return 'daily'\n if (opts.monthly) return 'monthly'\n return 'weekly'\n}\n\nfunction apiOptions(opts: Record<string, unknown>): { apiUrl: string; apiKey: string } {\n const apiKey = String(opts.apiKey ?? process.env.MCP_SCRAPER_API_KEY ?? '').trim()\n if (!apiKey) throw new Error('MCP_SCRAPER_API_KEY is required. Pass --api-key or set the environment variable.')\n return {\n apiUrl: String(opts.apiUrl ?? process.env.MCP_SCRAPER_API_URL ?? 'https://mcpscraper.dev').replace(/\\/$/, ''),\n apiKey,\n }\n}\n\nfunction openExternalUrl(url: string): boolean {\n const command = process.platform === 'darwin'\n ? 'open'\n : process.platform === 'win32'\n ? 'cmd'\n : 'xdg-open'\n const args = process.platform === 'win32' ? ['/c', 'start', '', url] : [url]\n try {\n const child = spawn(command, args, { detached: true, stdio: 'ignore' })\n child.unref()\n return true\n } catch {\n return false\n }\n}\n\nasync function apiRequest<T>(path: string, method: string, opts: Record<string, unknown>, body?: unknown): Promise<T> {\n const { apiUrl, apiKey } = apiOptions(opts)\n const res = await fetch(`${apiUrl}${path}`, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: body == null ? undefined : JSON.stringify(body),\n })\n const data = await res.json().catch(() => ({}))\n if (!res.ok) {\n const message = typeof (data as { error?: unknown }).error === 'string'\n ? (data as { error: string }).error\n : `API request failed with ${res.status}`\n throw new Error(message)\n }\n return data as T\n}\n\nfunction addWorkflowInputOptions(command: Command): Command {\n return command\n .option('--keyword <keyword>', 'Agent packet keyword')\n .option('--domain <domain>', 'Target domain')\n .option('--url <url>', 'Target page URL')\n .option('--location <location>', 'Target location')\n .option('--max-results <n>', 'Maximum SERP or Maps results')\n .option('--max-questions <n>', 'Maximum PAA questions')\n .option('--extract-top <n>', 'Top result pages or citation pages to extract')\n .option('--depth <n>', 'PAA expansion depth')\n .option('--no-serp', 'Skip SERP evidence for agent packet')\n .option('--no-paa', 'Skip PAA evidence for agent packet')\n .option('--query <query>', 'Business category or workflow query')\n .option('--state <state>', 'US state')\n .option('--min-pop <n>', 'Minimum city population')\n .option('--max-cities <n>', 'Maximum selected cities')\n .option('--per-city <n>', 'Maps results per city')\n .option('--concurrency <n>', 'City search concurrency')\n .option('--proxy-mode <mode>', 'Proxy mode: location, configured, or none')\n .option('--hydrate-top <n>', 'Profiles to hydrate per city for competitive audits')\n .option('--reviews <n>', 'Review cards to collect per hydrated profile')\n .option('--no-return-partial', 'Fail instead of writing partial artifacts')\n}\n\nexport function buildHumanCli(): Command {\n const program = new Command()\n program\n .name('mcp-scraper-cli')\n .description('Human CLI for MCP Scraper setup, workflows, reports, and agent-ready SEO artifacts.')\n .version(PACKAGE_VERSION)\n\n program.command('doctor')\n .description('Check setup, API key, output directory, package version, and recommended MCP config.')\n .option('--api-key <key>', 'MCP Scraper API key')\n .option('--api-url <url>', 'MCP Scraper API URL', 'https://mcpscraper.dev')\n .option('--output-dir <path>', 'Output directory to test')\n .option('--json', 'Print machine-readable JSON')\n .action(async (opts) => {\n const output = await runDoctor({ apiKey: opts.apiKey, apiUrl: opts.apiUrl, outputDir: opts.outputDir })\n writeOutput(opts.json ? output : renderDoctor(output), opts.json)\n if (!output.ok) process.exitCode = 1\n })\n\n const billing = program.command('billing').description('Inspect billing and start checkout flows.')\n const billingConcurrency = billing.command('concurrency').description('Manage MCP Scraper concurrency slots.')\n\n billingConcurrency.command('info')\n .description('Show current concurrency limit and extra-slot price.')\n .option('--api-key <key>', 'MCP Scraper API key')\n .option('--api-url <url>', 'MCP Scraper API URL', 'https://mcpscraper.dev')\n .option('--json', 'Print machine-readable JSON')\n .action(async (opts) => {\n const result = await apiRequest<{ concurrency: Record<string, unknown> }>('/billing/credits', 'POST', opts, {})\n if (opts.json) writeOutput(result.concurrency, true)\n else {\n const upgrade = result.concurrency?.upgrade as Record<string, unknown> | undefined\n writeOutput([\n `Current limit: ${result.concurrency?.current_limit ?? 'unknown'} concurrent operations`,\n `Extra slots: ${result.concurrency?.current_extra_slots ?? 'unknown'}`,\n `Extra concurrency slot: ${upgrade?.price_label ?? '$5/month'}`,\n `Upgrade command: ${upgrade?.terminal_command ?? 'mcp-scraper-cli billing concurrency checkout'}`,\n ].join('\\n'), false)\n }\n })\n\n billingConcurrency.command('checkout')\n .description('Create a hosted Stripe checkout for one extra concurrency slot.')\n .option('--api-key <key>', 'MCP Scraper API key')\n .option('--api-url <url>', 'MCP Scraper API URL', 'https://mcpscraper.dev')\n .option('--json', 'Print machine-readable JSON')\n .option('--no-open', 'Print the checkout URL without opening a browser')\n .action(async (opts) => {\n const result = await apiRequest<{ checkout_url: string; price?: { price_label?: string }; next_step?: string }>('/billing/concurrency/terminal-checkout', 'POST', opts, {})\n if (opts.json) {\n writeOutput(result, true)\n return\n }\n const opened = opts.open !== false && openExternalUrl(result.checkout_url)\n writeOutput([\n `Extra concurrency slot: ${result.price?.price_label ?? '$5/month'}`,\n opened ? `Opened checkout: ${result.checkout_url}` : `Checkout URL: ${result.checkout_url}`,\n result.next_step ?? 'Complete checkout, then retry the MCP request.',\n ].join('\\n'), false)\n })\n\n billing.command('subscribe <tier>')\n .description('Subscribe to a plan (starter | growth | scale) via a hosted Stripe checkout link.')\n .option('--api-key <key>', 'MCP Scraper API key')\n .option('--api-url <url>', 'MCP Scraper API URL', 'https://mcpscraper.dev')\n .option('--json', 'Print machine-readable JSON')\n .option('--no-open', 'Print the checkout URL without opening a browser')\n .action(async (tier, opts) => {\n const result = await apiRequest<{ checkout_url?: string; updated?: boolean; tier?: string; label?: string; monthly_usd?: number; credits_per_month?: number; concurrency?: number; intro?: string | null; message?: string; next_step?: string }>('/billing/subscribe/terminal-checkout', 'POST', opts, { tier: String(tier).toLowerCase() })\n if (opts.json) { writeOutput(result, true); return }\n if (result.updated) { writeOutput(result.message ?? `Switched to ${result.tier}.`, false); return }\n const opened = opts.open !== false && !!result.checkout_url && openExternalUrl(result.checkout_url)\n writeOutput([\n `Plan: ${result.label ?? tier} — $${result.monthly_usd}/mo · ${result.credits_per_month?.toLocaleString()} credits/mo · ${result.concurrency} concurrency${result.intro ? ` · ${result.intro}` : ''}`,\n opened ? `Opened checkout: ${result.checkout_url}` : `Checkout URL: ${result.checkout_url}`,\n result.next_step ?? 'Complete payment in the browser.',\n ].join('\\n'), false)\n })\n\n const agent = program.command('agent').description('Generate AI-agent install configs and workflow prompts.')\n agent.command('install <host>')\n .description('Print or apply install/config instructions for codex, claude/claude-code, or claude-desktop.')\n .option('--api-key <key>', 'API key to place in generated config')\n .option('--package <spec>', 'npm package spec', 'mcp-scraper@latest')\n .option('--browser-profile <name>', 'Default saved browser profile for browser_open sessions.')\n .option('--save-browser-profile-changes', 'Persist cookies and browser storage back to the named browser profile when sessions close')\n .option('--apply', 'Apply the config to this client when supported. For Claude Code, this upserts the user-scope mcp-scraper server.')\n .option('--json', 'Print machine-readable JSON')\n .action(async (hostInput: AgentHost, opts) => {\n const host = normalizeAgentHost(hostInput)\n const apiKey = opts.apiKey ?? process.env.MCP_SCRAPER_API_KEY\n if (opts.apply) {\n if (host !== 'claude') throw new Error('--apply is currently supported for Claude Code only. Use host \"claude\" or \"claude-code\".')\n if (!apiKey?.trim()) {\n throw new Error('MCP_SCRAPER_API_KEY is required for --apply. Set it in the environment or pass --api-key.')\n }\n\n const configOptions = {\n apiKey,\n packageSpec: opts.package,\n browserProfileName: opts.browserProfile,\n browserProfileSaveChanges: opts.saveBrowserProfileChanges,\n }\n const remove = await runLocalCommand('claude', claudeMcpRemoveArgs())\n const add = await runLocalCommand('claude', claudeMcpAddArgs(configOptions))\n if (add.code !== 0) {\n const reason = maskSecrets([add.stderr, add.stdout].filter(Boolean).join('\\n').trim())\n throw new Error([\n 'Claude Code MCP registration failed.',\n reason || 'No error output returned.',\n 'Make sure Claude Code is installed and the `claude` command is on PATH.',\n ].join('\\n'))\n }\n const list = await runLocalCommand('claude', ['mcp', 'list'])\n const result = {\n host: 'claude',\n applied: true,\n replacedExisting: remove.code === 0,\n command: 'npx',\n args: ['-y', '-p', opts.package, 'mcp-scraper'],\n nextStep: 'Fully exit Claude Code, start a new Claude terminal, then run: claude mcp list',\n list: maskSecrets([list.stdout, list.stderr].filter(Boolean).join('\\n').trim()),\n }\n if (opts.json) {\n writeOutput(result, true)\n return\n }\n writeOutput([\n 'Applied Claude Code MCP config: mcp-scraper',\n remove.code === 0 ? 'Replaced existing mcp-scraper entry.' : 'No existing mcp-scraper entry found; added a new one.',\n 'Command: npx -y -p ' + opts.package + ' mcp-scraper',\n opts.browserProfile ? `Browser profile: ${opts.browserProfile}` : '',\n '',\n 'Next step: fully exit Claude Code, start a new Claude terminal, then run:',\n ' claude mcp list',\n '',\n result.list ? `Current Claude MCP list:\\n${result.list}` : '',\n ].filter(Boolean).join('\\n'), false)\n return\n }\n const text = renderAgentInstall(host, {\n apiKey: opts.apiKey,\n packageSpec: opts.package,\n browserProfileName: opts.browserProfile,\n browserProfileSaveChanges: opts.saveBrowserProfileChanges,\n })\n writeOutput(opts.json ? { host, text } : text, opts.json)\n })\n\n agent.command('prompt [name]')\n .description('Print an agent prompt template.')\n .option('--json', 'Print machine-readable JSON')\n .action((name: string | undefined, opts) => {\n if (!name) {\n writeOutput(opts.json ? { prompts: listPrompts() } : listPrompts().join('\\n'), opts.json)\n return\n }\n const text = renderPrompt(name)\n writeOutput(opts.json ? { name, text } : text, opts.json)\n })\n\n const workflow = program.command('workflow').description('Run named SEO workflows.')\n workflow.command('list')\n .description('List available workflows.')\n .option('--json', 'Print machine-readable JSON')\n .action((opts) => {\n const rows = listWorkflowDefinitions()\n if (opts.json) writeOutput({ workflows: rows }, true)\n else writeOutput(rows.map(row => `${row.id}\\t${row.title}\\n ${row.description}`).join('\\n'), false)\n })\n\n workflow.command('run <id>')\n .description('Run a workflow and save local artifacts.')\n .option('--api-key <key>', 'MCP Scraper API key')\n .option('--api-url <url>', 'MCP Scraper API URL', 'https://mcpscraper.dev')\n .option('--output-dir <path>', 'Workflow output directory')\n .option('--json', 'Print machine-readable JSON')\n .option('--keyword <keyword>', 'Agent packet keyword')\n .option('--domain <domain>', 'Target domain')\n .option('--url <url>', 'Target page URL')\n .option('--location <location>', 'Target location')\n .option('--max-results <n>', 'Maximum SERP or Maps results')\n .option('--max-questions <n>', 'Maximum PAA questions')\n .option('--extract-top <n>', 'Top result pages or citation pages to extract')\n .option('--depth <n>', 'PAA expansion depth')\n .option('--no-serp', 'Skip SERP evidence for agent packet')\n .option('--no-paa', 'Skip PAA evidence for agent packet')\n .option('--query <query>', 'Business category or workflow query')\n .option('--state <state>', 'US state')\n .option('--min-pop <n>', 'Minimum city population')\n .option('--max-cities <n>', 'Maximum selected cities')\n .option('--per-city <n>', 'Maps results per city')\n .option('--concurrency <n>', 'City search concurrency')\n .option('--proxy-mode <mode>', 'Proxy mode: location, configured, or none')\n .option('--hydrate-top <n>', 'Profiles to hydrate per city for competitive audits')\n .option('--reviews <n>', 'Review cards to collect per hydrated profile')\n .option('--no-return-partial', 'Fail instead of writing partial artifacts')\n .action(async (id: string, opts) => {\n const summary = await runWorkflow(id, workflowInput(id, opts), {\n apiKey: opts.apiKey,\n apiUrl: opts.apiUrl,\n outputDir: opts.outputDir,\n })\n if (opts.json) writeOutput(summary, true)\n else {\n writeOutput([\n `${summary.title}: ${summary.status}`,\n summary.summary,\n summary.reportPath ? `Report: ${summary.reportPath}` : '',\n summary.warnings.length ? `Warnings:\\n${summary.warnings.map(w => `- ${w}`).join('\\n')}` : '',\n ].filter(Boolean).join('\\n'), false)\n }\n })\n\n const report = program.command('report').description('List and open local workflow reports.')\n report.command('list')\n .description('List recent workflow reports.')\n .option('--output-dir <path>', 'Workflow output directory')\n .option('--json', 'Print machine-readable JSON')\n .action(async (opts) => {\n const reports = await listWorkflowReports(opts.outputDir)\n writeOutput(opts.json ? { reports } : reports.map(r => `${r.startedAt}\\t${r.workflow}\\t${r.status}\\t${r.reportPath ?? r.manifestPath}`).join('\\n'), opts.json)\n })\n report.command('path [id]')\n .description('Print a report path. Defaults to last.')\n .option('--output-dir <path>', 'Workflow output directory')\n .option('--json', 'Print machine-readable JSON')\n .action(async (id = 'last', opts) => {\n const found = await findWorkflowReport(id, opts.outputDir)\n if (!found?.reportPath) throw new Error(`No report found for \"${id}\"`)\n writeOutput(opts.json ? { path: found.reportPath, run: found } : found.reportPath, opts.json)\n })\n report.command('open [id]')\n .description('Open a report. Defaults to last.')\n .option('--output-dir <path>', 'Workflow output directory')\n .option('--json', 'Print machine-readable JSON instead of opening')\n .action(async (id = 'last', opts) => {\n if (opts.json) {\n const found = await findWorkflowReport(id, opts.outputDir)\n if (!found?.reportPath) throw new Error(`No report found for \"${id}\"`)\n writeOutput({ path: found.reportPath, run: found }, true)\n return\n }\n const path = await openWorkflowReport(id, opts.outputDir)\n writeOutput(`Opened: ${path}`, false)\n })\n\n const schedule = program.command('schedule').description('Create and manage hosted workflow schedules.')\n addWorkflowInputOptions(schedule.command('create <workflowId>')\n .description('Create a recurring hosted workflow schedule.')\n .option('--api-key <key>', 'MCP Scraper API key')\n .option('--api-url <url>', 'MCP Scraper API URL', 'https://mcpscraper.dev')\n .option('--name <name>', 'Schedule name')\n .option('--daily', 'Run daily')\n .option('--weekly', 'Run weekly')\n .option('--monthly', 'Run monthly')\n .option('--timezone <tz>', 'Schedule timezone', 'UTC')\n .option('--webhook <url>', 'HTTPS webhook URL')\n .option('--next-run-at <iso>', 'First run time as an ISO timestamp')\n .option('--json', 'Print machine-readable JSON'))\n .action(async (workflowId: string, opts) => {\n const result = await apiRequest('/workflows/schedules', 'POST', opts, {\n workflowId,\n name: opts.name,\n input: workflowInput(workflowId, opts),\n cadence: cadenceOpt(opts),\n timezone: opts.timezone,\n webhookUrl: opts.webhook,\n nextRunAt: opts.nextRunAt,\n })\n writeOutput(result, opts.json)\n })\n\n schedule.command('list')\n .description('List hosted workflow schedules.')\n .option('--api-key <key>', 'MCP Scraper API key')\n .option('--api-url <url>', 'MCP Scraper API URL', 'https://mcpscraper.dev')\n .option('--json', 'Print machine-readable JSON')\n .action(async (opts) => {\n const result = await apiRequest<{ schedules: Array<Record<string, unknown>> }>('/workflows/schedules', 'GET', opts)\n if (opts.json) writeOutput(result, true)\n else writeOutput(result.schedules.map(scheduleRow => `${scheduleRow.id}\\t${scheduleRow.status}\\t${scheduleRow.workflow_id}\\t${scheduleRow.next_run_at ?? ''}`).join('\\n'), false)\n })\n\n schedule.command('pause <id>')\n .description('Pause a hosted workflow schedule.')\n .option('--api-key <key>', 'MCP Scraper API key')\n .option('--api-url <url>', 'MCP Scraper API URL', 'https://mcpscraper.dev')\n .option('--json', 'Print machine-readable JSON')\n .action(async (id: string, opts) => writeOutput(await apiRequest(`/workflows/schedules/${id}`, 'PATCH', opts, { status: 'paused' }), opts.json))\n\n schedule.command('resume <id>')\n .description('Resume a hosted workflow schedule.')\n .option('--api-key <key>', 'MCP Scraper API key')\n .option('--api-url <url>', 'MCP Scraper API URL', 'https://mcpscraper.dev')\n .option('--json', 'Print machine-readable JSON')\n .action(async (id: string, opts) => writeOutput(await apiRequest(`/workflows/schedules/${id}`, 'PATCH', opts, { status: 'active' }), opts.json))\n\n schedule.command('delete <id>')\n .description('Delete a hosted workflow schedule.')\n .option('--api-key <key>', 'MCP Scraper API key')\n .option('--api-url <url>', 'MCP Scraper API URL', 'https://mcpscraper.dev')\n .option('--json', 'Print machine-readable JSON')\n .action(async (id: string, opts) => writeOutput(await apiRequest(`/workflows/schedules/${id}`, 'DELETE', opts), opts.json))\n\n schedule.command('run <id>')\n .description('Run a hosted workflow schedule now.')\n .option('--api-key <key>', 'MCP Scraper API key')\n .option('--api-url <url>', 'MCP Scraper API URL', 'https://mcpscraper.dev')\n .option('--json', 'Print machine-readable JSON')\n .action(async (id: string, opts) => writeOutput(await apiRequest(`/workflows/schedules/${id}/run`, 'POST', opts, {}), opts.json))\n\n const runs = program.command('runs').description('Inspect and download hosted workflow runs.')\n runs.command('list')\n .description('List hosted workflow runs.')\n .option('--api-key <key>', 'MCP Scraper API key')\n .option('--api-url <url>', 'MCP Scraper API URL', 'https://mcpscraper.dev')\n .option('--json', 'Print machine-readable JSON')\n .action(async (opts) => {\n const result = await apiRequest<{ runs: Array<Record<string, unknown>> }>('/workflows/runs', 'GET', opts)\n if (opts.json) writeOutput(result, true)\n else writeOutput(result.runs.map(run => `${run.id}\\t${run.status}\\t${run.workflow_id}\\t${run.queued_at}`).join('\\n'), false)\n })\n\n runs.command('status <id>')\n .description('Show a hosted workflow run.')\n .option('--api-key <key>', 'MCP Scraper API key')\n .option('--api-url <url>', 'MCP Scraper API URL', 'https://mcpscraper.dev')\n .option('--json', 'Print machine-readable JSON')\n .action(async (id: string, opts) => writeOutput(await apiRequest(`/workflows/runs/${id}`, 'GET', opts), opts.json))\n\n runs.command('download <id>')\n .description('Download hosted workflow run artifacts.')\n .option('--api-key <key>', 'MCP Scraper API key')\n .option('--api-url <url>', 'MCP Scraper API URL', 'https://mcpscraper.dev')\n .option('--output-dir <path>', 'Download directory')\n .option('--json', 'Print machine-readable JSON')\n .action(async (id: string, opts) => {\n const result = await apiRequest<{ run: { id: string; artifacts?: Array<{ id: string; label: string; path: string }> } }>(`/workflows/runs/${id}`, 'GET', opts)\n const { apiUrl, apiKey } = apiOptions(opts)\n const outDir = join(opts.outputDir ?? workflowOutputBaseDir(), 'workflow-downloads', id)\n await mkdir(outDir, { recursive: true })\n const downloaded: string[] = []\n for (const artifact of result.run.artifacts ?? []) {\n const res = await fetch(`${apiUrl}/workflows/runs/${id}/artifacts/${artifact.id}`, { headers: { 'x-api-key': apiKey } })\n if (!res.ok) throw new Error(`Failed to download ${artifact.label}: HTTP ${res.status}`)\n const file = join(outDir, basename(artifact.path))\n await writeFile(file, Buffer.from(await res.arrayBuffer()))\n downloaded.push(file)\n }\n writeOutput(opts.json ? { runId: id, files: downloaded } : downloaded.join('\\n'), opts.json)\n })\n\n return program\n}\n\nexport async function runHumanCli(argv = process.argv): Promise<void> {\n await buildHumanCli().parseAsync(argv)\n}\n","export const PACKAGE_VERSION = '0.18.0'\n","export type AgentHost = 'codex' | 'claude' | 'claude-code' | 'claude-desktop'\n\nexport interface AgentConfigOptions {\n apiKey?: string\n packageSpec?: string\n browserProfileName?: string\n browserProfileSaveChanges?: boolean\n}\n\nfunction apiKeyValue(options: AgentConfigOptions): string {\n return options.apiKey?.trim() || 'sk_live_your_key'\n}\n\nfunction packageSpec(options: AgentConfigOptions): string {\n return options.packageSpec?.trim() || 'mcp-scraper@latest'\n}\n\nexport function combinedNpxArgs(options: AgentConfigOptions = {}): string[] {\n return ['-y', '-p', packageSpec(options), 'mcp-scraper']\n}\n\nfunction envConfig(options: AgentConfigOptions): Record<string, string> {\n const env: Record<string, string> = { MCP_SCRAPER_API_KEY: apiKeyValue(options) }\n const profileName = options.browserProfileName?.trim()\n if (profileName) env.BROWSER_AGENT_PROFILE_NAME = profileName\n if (options.browserProfileSaveChanges === true) env.BROWSER_AGENT_PROFILE_SAVE_CHANGES = 'true'\n return env\n}\n\nfunction tomlInlineTable(value: Record<string, string>): string {\n const entries = Object.entries(value).map(([key, item]) => `${key} = ${JSON.stringify(item)}`)\n return `{ ${entries.join(', ')} }`\n}\n\nexport function renderCodexConfig(options: AgentConfigOptions = {}): string {\n return [\n '[mcp_servers.mcp-scraper]',\n 'command = \"npx\"',\n `args = ${JSON.stringify(combinedNpxArgs(options))}`,\n `env = ${tomlInlineTable(envConfig(options))}`,\n ].join('\\n')\n}\n\nexport function renderClaudeCommand(options: AgentConfigOptions = {}): string {\n const env = Object.entries(envConfig(options)).map(([key, value]) => ` --env ${key}=${value}`)\n return [\n 'claude mcp add mcp-scraper --scope user',\n ...env,\n ` -- npx ${combinedNpxArgs(options).join(' ')}`,\n ].join(' \\\\\\n')\n}\n\nexport function claudeMcpRemoveArgs(): string[] {\n return ['mcp', 'remove', 'mcp-scraper', '-s', 'user']\n}\n\nexport function claudeMcpAddArgs(options: AgentConfigOptions = {}): string[] {\n const args = ['mcp', 'add', 'mcp-scraper', '--scope', 'user']\n for (const [key, value] of Object.entries(envConfig(options))) {\n args.push('--env', `${key}=${value}`)\n }\n args.push('--', 'npx', ...combinedNpxArgs(options))\n return args\n}\n\nexport function normalizeAgentHost(host: string): AgentHost {\n if (host === 'claude-code') return 'claude'\n if (host === 'claude' || host === 'codex' || host === 'claude-desktop') return host\n throw new Error('Unknown host \"' + host + '\". Use: codex, claude, claude-code, or claude-desktop')\n}\n\nexport function renderClaudeDesktopConfig(options: AgentConfigOptions = {}): string {\n return JSON.stringify({\n mcpServers: {\n 'mcp-scraper': {\n command: 'npx',\n args: combinedNpxArgs(options),\n env: envConfig(options),\n },\n },\n }, null, 2)\n}\n\nexport function renderAgentInstall(host: AgentHost, options: AgentConfigOptions = {}): string {\n const normalizedHost = normalizeAgentHost(host)\n const restart = 'Restart the MCP client so it starts a fresh npx process.'\n const applyCommand = `MCP_SCRAPER_API_KEY=${apiKeyValue(options)} npx -y -p mcp-scraper@latest mcp-scraper-cli agent install claude --apply`\n if (normalizedHost === 'codex') {\n return [\n '# Codex MCP config',\n renderCodexConfig(options),\n '',\n restart,\n ].join('\\n')\n }\n if (normalizedHost === 'claude') {\n return [\n '# Claude Code command',\n renderClaudeCommand(options),\n '',\n '# One-command Claude Code setup',\n applyCommand,\n '',\n restart,\n ].join('\\n')\n }\n return [\n '# Claude Desktop config',\n renderClaudeDesktopConfig(options),\n '',\n 'Desktop Extension: https://mcpscraper.dev/downloads/mcp-scraper.mcpb',\n restart,\n ].join('\\n')\n}\n","import { access, mkdir, readFile } from 'node:fs/promises'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { PACKAGE_VERSION } from '../version.js'\nimport { combinedNpxArgs } from './agent-config.js'\n\nexport type DoctorStatus = 'pass' | 'warn' | 'fail' | 'skip'\n\nexport interface DoctorCheck {\n id: string\n label: string\n status: DoctorStatus\n detail: string\n fix?: string\n}\n\nexport interface DoctorOptions {\n apiKey?: string\n apiUrl?: string\n outputDir?: string\n fetchImpl?: typeof fetch\n}\n\nexport interface DoctorOutput {\n ok: boolean\n version: string\n npmLatest: string | null\n checks: DoctorCheck[]\n recommendedConfig: {\n command: 'npx'\n args: string[]\n env: Record<string, string>\n }\n}\n\nfunction status(ok: boolean, warn = false): DoctorStatus {\n if (ok) return 'pass'\n return warn ? 'warn' : 'fail'\n}\n\nfunction parseMajor(version: string): number {\n return Number(version.replace(/^v/, '').split('.')[0] ?? 0)\n}\n\nasync function readKeyFile(): Promise<string | null> {\n const path = process.env.MCP_SCRAPER_KEY_PATH?.trim() || join(homedir(), '.mcp-scraper-key')\n try {\n const value = (await readFile(path, 'utf8')).trim()\n return value || null\n } catch {\n return null\n }\n}\n\nasync function npmLatest(fetchImpl: typeof fetch): Promise<string | null> {\n try {\n const res = await fetchImpl('https://registry.npmjs.org/mcp-scraper/latest', {\n signal: AbortSignal.timeout(5_000),\n })\n if (!res.ok) return null\n const data = await res.json() as { version?: string }\n return data.version ?? null\n } catch {\n return null\n }\n}\n\nexport async function runDoctor(options: DoctorOptions = {}): Promise<DoctorOutput> {\n const fetchImpl = options.fetchImpl ?? fetch\n const apiUrl = (options.apiUrl ?? process.env.MCP_SCRAPER_API_URL ?? 'https://mcpscraper.dev').replace(/\\/$/, '')\n const outputDir = options.outputDir ?? process.env.MCP_SCRAPER_OUTPUT_DIR ?? join(homedir(), 'Downloads', 'mcp-scraper')\n const configuredKey = options.apiKey?.trim() || process.env.MCP_SCRAPER_API_KEY?.trim() || await readKeyFile()\n const latest = await npmLatest(fetchImpl)\n\n const checks: DoctorCheck[] = []\n const nodeMajor = parseMajor(process.version)\n checks.push({\n id: 'node',\n label: 'Node.js',\n status: status(nodeMajor >= 20),\n detail: process.version,\n fix: nodeMajor >= 20 ? undefined : 'Install Node.js 20 or newer.',\n })\n\n checks.push({\n id: 'package_version',\n label: 'Local package',\n status: latest && latest !== PACKAGE_VERSION ? 'warn' : 'pass',\n detail: latest ? `local ${PACKAGE_VERSION}, npm latest ${latest}` : `local ${PACKAGE_VERSION}, npm latest unavailable`,\n fix: latest && latest !== PACKAGE_VERSION ? 'Use mcp-scraper@latest and restart the MCP client.' : undefined,\n })\n\n checks.push({\n id: 'api_key',\n label: 'API key',\n status: configuredKey ? 'pass' : 'warn',\n detail: configuredKey ? 'configured' : 'not configured',\n fix: configuredKey ? undefined : 'Set MCP_SCRAPER_API_KEY or pass --api-key.',\n })\n\n try {\n await mkdir(outputDir, { recursive: true })\n await access(outputDir)\n checks.push({ id: 'output_dir', label: 'Output directory', status: 'pass', detail: outputDir })\n } catch (err) {\n checks.push({\n id: 'output_dir',\n label: 'Output directory',\n status: 'fail',\n detail: outputDir,\n fix: err instanceof Error ? err.message : 'Create a writable output directory.',\n })\n }\n\n if (configuredKey) {\n try {\n const res = await fetchImpl(`${apiUrl}/me`, {\n headers: { 'x-api-key': configuredKey },\n signal: AbortSignal.timeout(8_000),\n })\n checks.push({\n id: 'api_reachability',\n label: 'Hosted API',\n status: res.ok ? 'pass' : 'fail',\n detail: `${apiUrl}/me returned ${res.status}`,\n fix: res.ok ? undefined : 'Verify the API key and account status.',\n })\n } catch (err) {\n checks.push({\n id: 'api_reachability',\n label: 'Hosted API',\n status: 'fail',\n detail: err instanceof Error ? err.message : String(err),\n fix: 'Check network access and MCP_SCRAPER_API_URL.',\n })\n }\n } else {\n checks.push({\n id: 'api_reachability',\n label: 'Hosted API',\n status: 'skip',\n detail: 'skipped because no API key is configured',\n })\n }\n\n checks.push({\n id: 'mcp_config',\n label: 'MCP command',\n status: 'pass',\n detail: `npx ${combinedNpxArgs().join(' ')}`,\n fix: 'Restart the MCP client after package updates.',\n })\n\n return {\n ok: checks.every(check => check.status === 'pass' || check.status === 'skip'),\n version: PACKAGE_VERSION,\n npmLatest: latest,\n checks,\n recommendedConfig: {\n command: 'npx',\n args: combinedNpxArgs(),\n env: { MCP_SCRAPER_API_KEY: configuredKey ? '$MCP_SCRAPER_API_KEY' : 'sk_live_your_key' },\n },\n }\n}\n\nexport function renderDoctor(output: DoctorOutput): string {\n const icon: Record<DoctorStatus, string> = { pass: 'PASS', warn: 'WARN', fail: 'FAIL', skip: 'SKIP' }\n const lines = [\n `mcp-scraper doctor v${output.version}`,\n '',\n ...output.checks.map(check => {\n const fix = check.fix ? `\\n Fix: ${check.fix}` : ''\n return `[${icon[check.status]}] ${check.label}: ${check.detail}${fix}`\n }),\n '',\n `Recommended MCP command: npx ${output.recommendedConfig.args.join(' ')}`,\n ]\n return lines.join('\\n')\n}\n\n","export const AGENT_PROMPTS: Record<string, string> = {\n 'agent-packet': [\n '# MCP Scraper Agent Packet Prompt',\n '',\n 'Use MCP Scraper as the evidence layer. Run the agent-packet workflow for the target keyword/domain, then treat `evidence.json`, `sources.csv`, and `competitors.csv` as source of truth.',\n '',\n 'Do not invent citations. If a recommendation is not supported by the packet, mark it as an assumption. Turn the evidence into a concise SEO brief, an implementation task list, and content recommendations tied to source rows.',\n ].join('\\n'),\n 'local-competitive-audit': [\n '# MCP Scraper Local Competitive Audit Prompt',\n '',\n 'Run the local-competitive-audit workflow for the niche and markets. Use the city summary, competitor CSV, and review-insight CSV to identify market difficulty, review themes, GBP category patterns, and weak competitors.',\n '',\n 'Ground recommendations in Maps rank position, review count, star rating, categories, profile details, and review topics. Do not overstate heuristic opportunity scores.',\n ].join('\\n'),\n 'directory-workflow': [\n '# MCP Scraper Directory Workflow Prompt',\n '',\n 'Use directory_workflow when the user wants cities selected by population and Google Maps candidates per city. Keep query and location separate. Preserve result_position, source_location, review stars/count, categories, and profile URLs for downstream CSV or directory use.',\n ].join('\\n'),\n 'map-comparison': [\n '# MCP Scraper Maps Comparison Prompt',\n '',\n 'Run the map-comparison workflow when the user wants to compare local Maps competitors in a city or across selected markets. Use `maps-results.csv`, `map-comparison.csv`, and `profile-insights.csv` as source of truth.',\n '',\n 'Ground recommendations in result_position, review_stars, review_count, category, website presence, review topics, and profile attributes. Treat review gaps and missing websites as opportunity signals, not guaranteed ranking factors.',\n ].join('\\n'),\n 'serp-comparison': [\n '# MCP Scraper SERP Comparison Prompt',\n '',\n 'Run the serp-comparison workflow when the user wants to know why competitors outrank a page or what the SERP rewards. Use organic results, extracted page headings, PAA questions, and AI Overview citations before making recommendations.',\n '',\n 'Tie each recommendation to `content-gaps.csv`, `page-comparison.csv`, `paa-questions.csv`, or `ai-overview-citations.csv`. Do not invent missing sections or citations.',\n ].join('\\n'),\n 'paa-expansion-brief': [\n '# MCP Scraper PAA Expansion Brief Prompt',\n '',\n 'Run the paa-expansion-brief workflow when the user wants to figure out what to write from People Also Ask expansion. Use `section-map.csv` to structure the brief and `paa-questions.csv` for exact customer-language headings.',\n '',\n 'Answer the highest-priority questions directly, preserve source URLs when present, and separate evidence-backed sections from assumptions.',\n ].join('\\n'),\n 'ai-overview-language': [\n '# MCP Scraper AI Overview Language Prompt',\n '',\n 'Run the ai-overview-language workflow when the user wants to know how to phrase content for AI Overview inclusion. Use `claim-patterns.csv`, `language-guidance.csv`, `ai-overview-citations.csv`, and PAA follow-ups as evidence.',\n '',\n 'Recommend concise answer blocks, criteria/step language, citation hooks, and follow-up sections. Do not claim the target will be cited; frame the output as evidence-based language guidance.',\n ].join('\\n'),\n 'ai-citation-monitor': [\n '# MCP Scraper AI Citation Monitor Prompt',\n '',\n 'Use search_serp and harvest_paa to check whether the target brand/domain appears in AI Overview citations, organic results, People Also Ask sources, local pack, forums, and videos. Save evidence before summarizing trends or gaps.',\n ].join('\\n'),\n 'serp-brief': [\n '# MCP Scraper SERP Brief Prompt',\n '',\n 'Use live SERP, PAA, AI Overview, forum, video, and source evidence to create a writer brief. Tie each recommended section to evidence rows and identify missing proof, entities, comparisons, and customer questions.',\n ].join('\\n'),\n}\n\nexport function listPrompts(): string[] {\n return Object.keys(AGENT_PROMPTS).sort()\n}\n\nexport function renderPrompt(name: string): string {\n const prompt = AGENT_PROMPTS[name]\n if (!prompt) throw new Error(`Unknown prompt \"${name}\". Available: ${listPrompts().join(', ')}`)\n return prompt\n}\n","import { mkdir, readFile, stat, writeFile } from 'node:fs/promises'\nimport { existsSync } from 'node:fs'\nimport { homedir, platform } from 'node:os'\nimport { dirname, join } from 'node:path'\nimport { execFile } from 'node:child_process'\nimport { rowsToCsv } from '../directory/csv.js'\nimport { slugify } from '../lib/slugify.js'\nimport type { WorkflowArtifact, WorkflowManifest, WorkflowStatus } from './types.js'\nimport { postToMemoryLibrary } from '../output/memory-library-sink.js'\n\nexport function workflowOutputBaseDir(outputDir?: string): string {\n return outputDir?.trim() || process.env.MCP_SCRAPER_OUTPUT_DIR?.trim() || join(homedir(), 'Downloads', 'mcp-scraper')\n}\n\nfunction timestamp(): string {\n return new Date().toISOString().replace(/[:.]/g, '-')\n}\n\nfunction safeSlug(value: string): string {\n return slugify(value).replace(/^-+|-+$/g, '').slice(0, 80) || 'run'\n}\n\nexport class ArtifactWriter {\n readonly artifacts: WorkflowArtifact[] = []\n\n constructor(\n readonly workflowId: string,\n readonly title: string,\n readonly runId: string,\n readonly baseDir: string,\n readonly runDir: string,\n readonly startedAt: string,\n readonly input: Record<string, unknown>,\n ) {}\n\n static async create(workflowId: string, title: string, input: Record<string, unknown>, outputDir?: string, forcedRunId?: string): Promise<ArtifactWriter> {\n const startedAt = new Date().toISOString()\n const runId = forcedRunId?.trim() || `${timestamp()}-${safeSlug(workflowId)}-${Math.random().toString(36).slice(2, 8)}`\n const nameSource = String(input.keyword ?? input.query ?? input.domain ?? input.state ?? workflowId)\n const baseDir = workflowOutputBaseDir(outputDir)\n const runDir = join(baseDir, 'workflows', workflowId, `${timestamp()}-${safeSlug(nameSource)}-${safeSlug(runId).slice(0, 20)}`)\n await mkdir(runDir, { recursive: true })\n return new ArtifactWriter(workflowId, title, runId, baseDir, runDir, startedAt, input)\n }\n\n private async remember(kind: WorkflowArtifact['kind'], label: string, path: string, rows?: number): Promise<string> {\n const size = await stat(path).then(s => s.size).catch(() => undefined)\n this.artifacts.push({ kind, label, path, bytes: size, rows })\n await postToMemoryLibrary({ title: `${this.title} ${label}`, content: `artifact: ${path}`, source: `mcp-scraper-workflow:${this.workflowId}:${this.runId}` })\n return path\n }\n\n async writeJson(label: string, relativePath: string, data: unknown): Promise<string> {\n const path = join(this.runDir, relativePath)\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, JSON.stringify(data, null, 2), 'utf8')\n return this.remember('json', label, path)\n }\n\n async writeText(label: string, relativePath: string, text: string, kind: WorkflowArtifact['kind'] = 'markdown'): Promise<string> {\n const path = join(this.runDir, relativePath)\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, text, 'utf8')\n return this.remember(kind, label, path)\n }\n\n async writeCsv(label: string, relativePath: string, headers: string[], rows: Array<Record<string, unknown>>): Promise<string> {\n const path = join(this.runDir, relativePath)\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, rowsToCsv(headers, rows), 'utf8')\n return this.remember('csv', label, path, rows.length)\n }\n\n async writeHtml(label: string, relativePath: string, html: string): Promise<string> {\n return this.writeText(label, relativePath, html, 'html_report')\n }\n\n async writeManifest(status: WorkflowStatus, counts: Record<string, number>, warnings: string[], errors: string[]): Promise<string> {\n const manifest: WorkflowManifest = {\n workflow: this.workflowId,\n title: this.title,\n runId: this.runId,\n status,\n startedAt: this.startedAt,\n completedAt: status === 'running' ? null : new Date().toISOString(),\n input: this.input,\n artifacts: this.artifacts,\n warnings,\n errors,\n counts,\n }\n const path = join(this.runDir, 'manifest.json')\n await writeFile(path, JSON.stringify(manifest, null, 2), 'utf8')\n await updateWorkflowIndex(manifest, path, this.baseDir)\n return path\n }\n}\n\ninterface WorkflowIndexEntry {\n workflow: string\n runId: string\n status: string\n startedAt: string\n reportPath: string | null\n manifestPath: string\n summary: string\n}\n\ninterface WorkflowIndex {\n runs: WorkflowIndexEntry[]\n}\n\nfunction indexPath(baseDir = workflowOutputBaseDir()): string {\n return join(baseDir, 'workflows', 'index.json')\n}\n\nasync function readIndex(baseDir?: string): Promise<WorkflowIndex> {\n const path = indexPath(baseDir)\n if (!existsSync(path)) return { runs: [] }\n try {\n return JSON.parse(await readFile(path, 'utf8')) as WorkflowIndex\n } catch {\n return { runs: [] }\n }\n}\n\nasync function updateWorkflowIndex(manifest: WorkflowManifest, manifestPath: string, baseDir: string): Promise<void> {\n if (manifest.status === 'running') return\n const path = indexPath(baseDir)\n const index = await readIndex(baseDir)\n const report = manifest.artifacts.find(a => a.kind === 'html_report')?.path ?? null\n const entry: WorkflowIndexEntry = {\n workflow: manifest.workflow,\n runId: manifest.runId,\n status: manifest.status,\n startedAt: manifest.startedAt,\n reportPath: report,\n manifestPath,\n summary: `${manifest.title} (${manifest.status})`,\n }\n index.runs = [entry, ...index.runs.filter(r => r.runId !== manifest.runId)].slice(0, 200)\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, JSON.stringify(index, null, 2), 'utf8')\n}\n\nexport async function listWorkflowReports(outputDir?: string): Promise<WorkflowIndexEntry[]> {\n return (await readIndex(workflowOutputBaseDir(outputDir))).runs\n}\n\nexport async function findWorkflowReport(id: string, outputDir?: string): Promise<WorkflowIndexEntry | null> {\n const runs = await listWorkflowReports(outputDir)\n if (id === 'last') return runs[0] ?? null\n return runs.find(run => run.runId === id) ?? null\n}\n\nexport async function openWorkflowReport(id: string, outputDir?: string): Promise<string> {\n const run = await findWorkflowReport(id, outputDir)\n if (!run?.reportPath) throw new Error(`No report found for \"${id}\"`)\n if (platform() === 'darwin') {\n await new Promise<void>((resolve, reject) => {\n execFile('open', [run.reportPath!], (err) => err ? reject(err) : resolve())\n })\n }\n return run.reportPath\n}\n","export function parseCsv(text: string): string[][] {\n const rows: string[][] = []\n let row: string[] = []\n let field = ''\n let quoted = false\n\n for (let i = 0; i < text.length; i += 1) {\n const ch = text[i]\n const next = text[i + 1]\n\n if (quoted) {\n if (ch === '\"' && next === '\"') {\n field += '\"'\n i += 1\n } else if (ch === '\"') {\n quoted = false\n } else {\n field += ch\n }\n continue\n }\n\n if (ch === '\"') {\n quoted = true\n } else if (ch === ',') {\n row.push(field)\n field = ''\n } else if (ch === '\\n') {\n row.push(field)\n rows.push(row)\n row = []\n field = ''\n } else if (ch !== '\\r') {\n field += ch\n }\n }\n\n if (field.length > 0 || row.length > 0) {\n row.push(field)\n rows.push(row)\n }\n\n return rows\n}\n\nexport function csvRecords(text: string): Array<Record<string, string>> {\n const rows = parseCsv(text).filter(row => row.some(cell => cell.trim() !== ''))\n const header = rows[0]?.map(cell => cell.trim()) ?? []\n return rows.slice(1).map((row) => {\n const record: Record<string, string> = {}\n for (let i = 0; i < header.length; i += 1) {\n record[header[i]] = row[i] ?? ''\n }\n return record\n })\n}\n\nexport function csvCell(value: unknown): string {\n if (value === null || value === undefined) return ''\n const text = String(value)\n return /[\",\\n\\r]/.test(text) ? `\"${text.replace(/\"/g, '\"\"')}\"` : text\n}\n\nexport function rowsToCsv(headers: string[], rows: Array<Record<string, unknown>>): string {\n return [\n headers.join(','),\n ...rows.map(row => headers.map(header => csvCell(row[header])).join(',')),\n ].join('\\n') + '\\n'\n}\n","export function slugify(s: string): string {\n return s.toLowerCase().replace(/\\s+/g, '-').replace(/[^a-z0-9-]/g, '');\n}\n","export async function postToMemoryLibrary(args: { title: string; content: string; source: string }): Promise<void> {\n const url = process.env.MCP_MEMORY_INGEST_URL\n const key = process.env.MCP_MEMORY_KEY\n if (!url || !key) return\n try {\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ data: { apiKey: key, title: args.title, content: args.content, source: args.source } }),\n })\n const body = (await res.json().catch(() => null)) as { result?: { error?: boolean; message?: string } } | null\n if (!res.ok || body?.result?.error) {\n console.warn('[memory-library-sink] ingest not accepted:', res.status, body?.result?.message ?? '')\n }\n } catch (err) {\n console.warn('[memory-library-sink] ingest failed:', (err as Error)?.message)\n }\n}\n\nexport function memoryLibrarySinkEnabled(): boolean {\n return Boolean(process.env.MCP_MEMORY_INGEST_URL && process.env.MCP_MEMORY_KEY)\n}\n","import { readFile } from 'node:fs/promises'\nimport { z } from 'zod'\nimport { ArtifactWriter, findWorkflowReport, listWorkflowReports, openWorkflowReport } from './artifact-writer.js'\nimport { WorkflowHttpClient } from './http-client.js'\nimport type { WorkflowArtifact, WorkflowDefinition, WorkflowRunContext, WorkflowRunOptions, WorkflowRunSummary } from './types.js'\nimport { agentPacketWorkflowDefinition } from './workflows/agent-packet.js'\nimport { directoryWorkflowDefinition } from './workflows/directory.js'\nimport { getLeadsWorkflowDefinition } from './workflows/get-leads.js'\nimport { localCompetitiveAuditWorkflowDefinition } from './workflows/local-competitive-audit.js'\nimport {\n aiOverviewLanguageWorkflowDefinition,\n mapComparisonWorkflowDefinition,\n paaExpansionBriefWorkflowDefinition,\n serpComparisonWorkflowDefinition,\n} from './workflows/comparison-briefs.js'\n\nconst DEFINITIONS = [\n directoryWorkflowDefinition,\n getLeadsWorkflowDefinition,\n agentPacketWorkflowDefinition,\n localCompetitiveAuditWorkflowDefinition,\n mapComparisonWorkflowDefinition,\n serpComparisonWorkflowDefinition,\n paaExpansionBriefWorkflowDefinition,\n aiOverviewLanguageWorkflowDefinition,\n] satisfies WorkflowDefinition<any, any>[]\n\nexport interface WorkflowStepArtifact {\n kind: WorkflowArtifact['kind']\n label: string\n path: string\n bytes?: number\n rows?: number\n content: string\n}\n\nexport interface WorkflowStepRunResult {\n runId: string\n workflowId: string\n title: string\n stepIndex: number\n stepId: string\n stepTitle: string\n totalSteps: number\n isLast: boolean\n output: Record<string, unknown>\n state: unknown\n warnings: string[]\n summary: WorkflowRunSummary | null\n artifacts: WorkflowStepArtifact[]\n}\n\nexport function listWorkflowDefinitions(): Array<Pick<WorkflowDefinition, 'id' | 'title' | 'description'>> {\n return DEFINITIONS.map(({ id, title, description }) => ({ id, title, description }))\n}\n\nexport function workflowDefinition(id: string): WorkflowDefinition<any, any> {\n const definition = DEFINITIONS.find(def => def.id === id)\n if (!definition) throw new Error(`Unknown workflow \"${id}\". Available: ${DEFINITIONS.map(def => def.id).join(', ')}`)\n return definition\n}\n\nexport function workflowStepCount(id: string): number {\n const definition = workflowDefinition(id)\n return definition.steps?.length ?? 1\n}\n\nexport function workflowSupportsSteps(id: string): boolean {\n const definition = workflowDefinition(id)\n return Boolean(definition.steps && definition.steps.length > 0)\n}\n\nfunction resolveApiKey(options: WorkflowRunOptions): string {\n const apiKey = options.apiKey?.trim() || process.env.MCP_SCRAPER_API_KEY?.trim()\n if (!apiKey) throw new Error('MCP_SCRAPER_API_KEY is required for workflow runs. Pass --api-key or set the environment variable.')\n return apiKey\n}\n\nfunction resolveApiUrl(options: WorkflowRunOptions): string {\n return options.apiUrl?.trim() || process.env.MCP_SCRAPER_API_URL?.trim() || 'https://mcpscraper.dev'\n}\n\nexport async function runWorkflow(id: string, rawInput: Record<string, unknown>, options: WorkflowRunOptions = {}): Promise<WorkflowRunSummary> {\n const definition = workflowDefinition(id)\n const input = definition.inputSchema.parse(rawInput)\n const apiKey = resolveApiKey(options)\n const apiUrl = resolveApiUrl(options)\n const artifacts = await ArtifactWriter.create(definition.id, definition.title, input as Record<string, unknown>, options.outputDir, options.runId)\n const client = new WorkflowHttpClient(apiUrl, apiKey, options.fetchImpl, options.headers)\n const ctx: WorkflowRunContext = { runId: artifacts.runId, startedAt: artifacts.startedAt, client, artifacts, signal: options.signal }\n try {\n if (definition.steps && definition.steps.length > 0) {\n let state = definition.createState ? definition.createState(input) : ({} as unknown)\n let summary: WorkflowRunSummary | null = null\n for (const step of definition.steps) {\n const outcome = await step.run({ input, state, ctx })\n state = outcome.state\n if (outcome.summary) summary = outcome.summary\n }\n if (!summary) throw new Error(`Workflow \"${id}\" produced no terminal step summary`)\n return summary\n }\n if (definition.run) return await definition.run(input, ctx)\n throw new Error(`Workflow \"${id}\" has neither steps nor a run() implementation`)\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n await artifacts.writeText('Failure', 'summary.md', `# ${definition.title}\\n\\n${message}\\n`)\n await artifacts.writeManifest('failed', {}, [], [message])\n throw err\n }\n}\n\nexport async function runWorkflowStep(id: string, rawInput: Record<string, unknown>, opts: {\n stepIndex: number\n state?: unknown\n options?: WorkflowRunOptions\n}): Promise<WorkflowStepRunResult> {\n const definition = workflowDefinition(id)\n const steps = definition.steps\n if (!steps || steps.length === 0) throw new Error(`Workflow \"${id}\" does not support stepwise execution`)\n if (opts.stepIndex < 0 || opts.stepIndex >= steps.length) {\n throw new Error(`Step index ${opts.stepIndex} is out of range for \"${id}\" (${steps.length} steps)`)\n }\n const options = opts.options ?? {}\n const input = definition.inputSchema.parse(rawInput)\n const apiKey = resolveApiKey(options)\n const apiUrl = resolveApiUrl(options)\n const artifacts = await ArtifactWriter.create(definition.id, definition.title, input as Record<string, unknown>, options.outputDir, options.runId)\n const client = new WorkflowHttpClient(apiUrl, apiKey, options.fetchImpl, options.headers)\n const ctx: WorkflowRunContext = { runId: artifacts.runId, startedAt: artifacts.startedAt, client, artifacts, signal: options.signal }\n const state = opts.state ?? (definition.createState ? definition.createState(input) : {})\n const step = steps[opts.stepIndex]\n const outcome = await step.run({ input, state, ctx })\n const writtenArtifacts: WorkflowStepArtifact[] = await Promise.all(\n artifacts.artifacts.map(async (artifact) => ({\n ...artifact,\n content: await readFile(artifact.path, 'utf8').catch(() => ''),\n })),\n )\n return {\n runId: artifacts.runId,\n workflowId: definition.id,\n title: definition.title,\n stepIndex: opts.stepIndex,\n stepId: step.id,\n stepTitle: step.title,\n totalSteps: steps.length,\n isLast: opts.stepIndex === steps.length - 1,\n output: outcome.output,\n state: outcome.state,\n warnings: outcome.warnings ?? [],\n summary: outcome.summary ?? null,\n artifacts: writtenArtifacts,\n }\n}\n\nexport { findWorkflowReport, listWorkflowReports, openWorkflowReport }\nexport { z }\n","import type { WorkflowApiClient } from './types.js'\n\nexport class WorkflowHttpClient implements WorkflowApiClient {\n constructor(\n private readonly apiUrl: string,\n private readonly apiKey: string,\n private readonly fetchImpl: typeof fetch = fetch,\n private readonly extraHeaders: Record<string, string> = {},\n ) {}\n\n async post<T>(path: string, body: Record<string, unknown>, timeoutMs = 180_000): Promise<T> {\n const res = await this.fetchImpl(`${this.apiUrl.replace(/\\/$/, '')}${path}`, {\n method: 'POST',\n headers: {\n ...this.extraHeaders,\n 'Content-Type': 'application/json',\n 'x-api-key': this.apiKey,\n },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(timeoutMs),\n })\n const data = await res.json().catch(() => ({}))\n if (!res.ok) {\n const message = typeof (data as { error?: unknown }).error === 'string'\n ? (data as { error: string }).error\n : `Workflow API ${path} failed with ${res.status}`\n throw new Error(message)\n }\n return data as T\n }\n}\n","import { z } from 'zod'\nimport { renderWorkflowReport } from '../report-renderer.js'\nimport type { WorkflowDefinition, WorkflowStepOutcome } from '../types.js'\n\nconst AgentPacketInputSchema = z.object({\n keyword: z.string().min(1),\n domain: z.string().optional(),\n location: z.string().optional(),\n maxQuestions: z.number().int().min(1).max(200).default(40),\n includeSerp: z.boolean().default(true),\n includePaa: z.boolean().default(true),\n includeAiOverview: z.boolean().default(true),\n returnPartial: z.boolean().default(true),\n})\n\ntype AgentPacketInput = z.infer<typeof AgentPacketInputSchema>\n\ninterface OrganicResult {\n position: number\n title: string\n url: string\n domain: string\n snippet?: string | null\n}\n\ninterface PaaRow {\n question: string\n answer?: string | null\n source_title?: string | null\n source_site?: string | null\n source_cite?: string | null\n}\n\ninterface HarvestLike {\n organicResults?: OrganicResult[]\n localPack?: Array<{ position: number; name: string; rating?: string | null; reviewCount?: string | null; websiteUrl?: string | null }>\n flat?: PaaRow[]\n aiOverview?: { detected?: boolean; text?: string | null; citations?: Array<{ text?: string; href?: string }> }\n}\n\nfunction normalizeDomain(value?: string | null): string | null {\n if (!value) return null\n try {\n const url = new URL(value.includes('://') ? value : `https://${value}`)\n return url.hostname.replace(/^www\\./, '').toLowerCase()\n } catch {\n return value.replace(/^https?:\\/\\//, '').replace(/^www\\./, '').split('/')[0]?.toLowerCase() || null\n }\n}\n\nfunction domainFromUrl(url: string): string {\n return normalizeDomain(url) ?? ''\n}\n\nfunction sourceRows(input: AgentPacketInput, serp: HarvestLike | null, paa: HarvestLike | null): Array<Record<string, unknown>> {\n const target = normalizeDomain(input.domain)\n const rows: Array<Record<string, unknown>> = []\n for (const result of serp?.organicResults ?? []) {\n const domain = normalizeDomain(result.domain) ?? domainFromUrl(result.url)\n rows.push({\n surface: 'organic',\n position: result.position,\n title: result.title,\n url: result.url,\n domain,\n question: '',\n answer_excerpt: result.snippet ?? '',\n is_target: target ? domain === target : false,\n is_competitor: target ? domain !== target : true,\n })\n }\n for (const row of paa?.flat ?? []) {\n const url = row.source_cite ?? ''\n const domain = normalizeDomain(row.source_site ?? '') ?? (url ? domainFromUrl(url) : '')\n rows.push({\n surface: 'paa',\n position: '',\n title: row.source_title ?? row.source_site ?? '',\n url,\n domain,\n question: row.question,\n answer_excerpt: (row.answer ?? '').slice(0, 240),\n is_target: target ? domain === target : false,\n is_competitor: target ? Boolean(domain && domain !== target) : Boolean(domain),\n })\n }\n for (const [i, cite] of (serp?.aiOverview?.citations ?? []).entries()) {\n const url = cite.href ?? ''\n const domain = url ? domainFromUrl(url) : ''\n rows.push({\n surface: 'ai_overview',\n position: i + 1,\n title: cite.text ?? '',\n url,\n domain,\n question: '',\n answer_excerpt: '',\n is_target: target ? domain === target : false,\n is_competitor: target ? Boolean(domain && domain !== target) : Boolean(domain),\n })\n }\n return rows\n}\n\nfunction competitorRows(rows: Array<Record<string, unknown>>, targetDomain: string | null): Array<Record<string, unknown>> {\n const byDomain = new Map<string, { organic: number[]; paa: number; ai: number; urls: Set<string> }>()\n for (const row of rows) {\n const domain = String(row.domain ?? '')\n if (!domain || domain === targetDomain) continue\n const entry = byDomain.get(domain) ?? { organic: [], paa: 0, ai: 0, urls: new Set<string>() }\n if (row.surface === 'organic' && row.position) entry.organic.push(Number(row.position))\n if (row.surface === 'paa') entry.paa += 1\n if (row.surface === 'ai_overview') entry.ai += 1\n if (row.url) entry.urls.add(String(row.url))\n byDomain.set(domain, entry)\n }\n return [...byDomain.entries()]\n .map(([domain, entry]) => ({\n domain,\n organic_best_position: entry.organic.length ? Math.min(...entry.organic) : '',\n organic_count: entry.organic.length,\n paa_mentions: entry.paa,\n ai_overview_citations: entry.ai,\n source_url_count: entry.urls.size,\n }))\n .sort((a, b) => Number(a.organic_best_position || 999) - Number(b.organic_best_position || 999))\n}\n\ninterface AgentPacketState {\n serp: HarvestLike | null\n paa: HarvestLike | null\n warnings: string[]\n}\n\nexport const agentPacketWorkflowDefinition: WorkflowDefinition<AgentPacketInput, AgentPacketState> = {\n id: 'agent-packet',\n title: 'Agent-Ready SEO Packet',\n description: 'Create an evidence folder for AI agents from live SERP/PAA/AI search surfaces.',\n inputSchema: AgentPacketInputSchema,\n createState: (): AgentPacketState => ({ serp: null, paa: null, warnings: [] }),\n steps: [\n {\n id: 'harvest-serp',\n title: 'Harvest organic SERP + AI Overview',\n async run({ input, state, ctx }): Promise<WorkflowStepOutcome<AgentPacketState>> {\n if (!input.includeSerp) {\n return { state, output: { skipped: true, reason: 'includeSerp is false' } }\n }\n try {\n const serp = await ctx.client.post<HarvestLike>('/harvest/sync', {\n query: input.keyword,\n location: input.location,\n serpOnly: true,\n maxQuestions: 1,\n format: 'json',\n }, 180_000)\n await ctx.artifacts.writeJson('SERP raw JSON', 'raw/serp.json', serp)\n return {\n state: { ...state, serp },\n output: {\n organicResults: serp.organicResults?.length ?? 0,\n localPack: serp.localPack?.length ?? 0,\n aiOverviewDetected: Boolean(serp.aiOverview?.detected),\n aiOverviewCitations: serp.aiOverview?.citations?.length ?? 0,\n },\n }\n } catch (err) {\n const message = `SERP evidence unavailable: ${err instanceof Error ? err.message : String(err)}`\n return { state: { ...state, warnings: [...state.warnings, message] }, output: { error: message }, warnings: [message] }\n }\n },\n },\n {\n id: 'harvest-paa',\n title: 'Harvest People Also Ask',\n async run({ input, state, ctx }): Promise<WorkflowStepOutcome<AgentPacketState>> {\n if (!input.includePaa) {\n return { state, output: { skipped: true, reason: 'includePaa is false' } }\n }\n try {\n const paa = await ctx.client.post<HarvestLike>('/harvest/sync', {\n query: input.keyword,\n location: input.location,\n maxQuestions: input.maxQuestions,\n format: 'json',\n }, 280_000)\n await ctx.artifacts.writeJson('PAA raw JSON', 'raw/paa.json', paa)\n return {\n state: { ...state, paa },\n output: { paaQuestions: paa.flat?.length ?? 0 },\n }\n } catch (err) {\n const message = `PAA evidence unavailable: ${err instanceof Error ? err.message : String(err)}`\n return { state: { ...state, warnings: [...state.warnings, message] }, output: { error: message }, warnings: [message] }\n }\n },\n },\n {\n id: 'assemble',\n title: 'Assemble evidence packet',\n async run({ input, state, ctx }): Promise<WorkflowStepOutcome<AgentPacketState>> {\n const { serp, paa } = state\n const warnings = state.warnings\n if (!serp && !paa && !input.returnPartial) throw new Error('No SEO evidence was collected')\n const rows = sourceRows(input, serp, paa)\n const target = normalizeDomain(input.domain)\n const competitors = competitorRows(rows, target)\n const evidence = {\n input,\n serp: serp ?? { status: 'skipped' },\n paa: paa ?? { status: 'skipped' },\n target: {\n domain: target,\n organicPositions: rows.filter(r => r.surface === 'organic' && r.is_target).map(r => Number(r.position)),\n citedInAiOverview: rows.some(r => r.surface === 'ai_overview' && r.is_target),\n citedInPaa: rows.some(r => r.surface === 'paa' && r.is_target),\n },\n competitors,\n warnings,\n }\n\n await ctx.artifacts.writeJson('Evidence JSON', 'evidence.json', evidence)\n await ctx.artifacts.writeCsv('Sources CSV', 'sources.csv', ['surface', 'position', 'title', 'url', 'domain', 'question', 'answer_excerpt', 'is_target', 'is_competitor'], rows)\n await ctx.artifacts.writeCsv('Competitors CSV', 'competitors.csv', ['domain', 'organic_best_position', 'organic_count', 'paa_mentions', 'ai_overview_citations', 'source_url_count'], competitors)\n\n const brief = [\n `# SEO Evidence Brief: ${input.keyword}`,\n '',\n `Location: ${input.location ?? 'not specified'}`,\n `Target domain: ${target ?? 'not specified'}`,\n '',\n '## Evidence Summary',\n `- Organic rows: ${rows.filter(r => r.surface === 'organic').length}`,\n `- PAA rows: ${rows.filter(r => r.surface === 'paa').length}`,\n `- AI Overview citations: ${rows.filter(r => r.surface === 'ai_overview').length}`,\n `- Competitor domains: ${competitors.length}`,\n '',\n '## Recommended Use',\n 'Use the CSV files as source of truth. Tie content recommendations to evidence rows and mark unsupported ideas as assumptions.',\n ].join('\\n')\n await ctx.artifacts.writeText('Brief', 'brief.md', brief)\n await ctx.artifacts.writeText('Agent tasks', 'tasks.md', [\n '# Agent Tasks',\n '',\n '- [ ] Read `evidence.json` before writing recommendations.',\n '- [ ] Compare the target domain against `competitors.csv`.',\n '- [ ] Use `sources.csv` for citations and source-grounded page sections.',\n '- [ ] Mark unsupported recommendations as assumptions.',\n ].join('\\n'))\n await ctx.artifacts.writeText('Agent instructions', 'agent-instructions.md', [\n '# Agent Instructions',\n '',\n 'You are working from an MCP Scraper SEO evidence packet. Use `evidence.json` and CSV files as source of truth. Do not invent citations. If a recommendation is not supported by evidence, mark it as an assumption.',\n ].join('\\n'))\n\n const summary = `${rows.length} evidence rows and ${competitors.length} competitor domains collected.`\n const reportPath = await ctx.artifacts.writeHtml('HTML report', 'report.html', renderWorkflowReport({\n title: 'Agent-Ready SEO Packet',\n subtitle: `${input.keyword}${input.location ? ` · ${input.location}` : ''}`,\n summary,\n warnings,\n tables: [\n { title: 'Competitor Domains', columns: ['domain', 'organic_best_position', 'organic_count', 'paa_mentions', 'ai_overview_citations', 'source_url_count'], rows: competitors.slice(0, 50) },\n { title: 'Evidence Sources', columns: ['surface', 'position', 'title', 'domain', 'question', 'is_target'], rows: rows.slice(0, 100) },\n ],\n }))\n const status = warnings.length ? 'partial' : 'succeeded'\n const counts = { sources: rows.length, competitors: competitors.length }\n await ctx.artifacts.writeManifest(status, counts, warnings, [])\n return {\n state,\n output: { sources: rows.length, competitors: competitors.length, status },\n summary: { title: 'Agent-Ready SEO Packet', summary, status, counts, warnings, errors: [], reportPath },\n }\n },\n },\n ],\n}\n\n","export interface ReportTable {\n title: string\n columns: string[]\n rows: Array<Record<string, unknown>>\n}\n\nexport interface ReportSection {\n title: string\n body: string\n}\n\nexport interface WorkflowReportInput {\n title: string\n subtitle?: string\n summary: string\n sections?: ReportSection[]\n tables?: ReportTable[]\n warnings?: string[]\n}\n\nexport function escapeHtml(value: unknown): string {\n return String(value ?? '')\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;')\n}\n\nfunction renderTable(table: ReportTable): string {\n const rows = table.rows.map(row => (\n `<tr>${table.columns.map(col => `<td>${escapeHtml(row[col])}</td>`).join('')}</tr>`\n )).join('\\n')\n return [\n `<section>`,\n `<h2>${escapeHtml(table.title)}</h2>`,\n `<div class=\"table-wrap\"><table>`,\n `<thead><tr>${table.columns.map(col => `<th>${escapeHtml(col)}</th>`).join('')}</tr></thead>`,\n `<tbody>${rows || `<tr><td colspan=\"${table.columns.length}\">No rows</td></tr>`}</tbody>`,\n `</table></div>`,\n `</section>`,\n ].join('\\n')\n}\n\nexport function renderWorkflowReport(input: WorkflowReportInput): string {\n const warnings = input.warnings?.length\n ? `<section class=\"warnings\"><h2>Warnings</h2><ul>${input.warnings.map(w => `<li>${escapeHtml(w)}</li>`).join('')}</ul></section>`\n : ''\n const sections = (input.sections ?? []).map(section => (\n `<section><h2>${escapeHtml(section.title)}</h2><p>${escapeHtml(section.body)}</p></section>`\n )).join('\\n')\n const tables = (input.tables ?? []).map(renderTable).join('\\n')\n\n return [\n '<!doctype html>',\n '<html lang=\"en\">',\n '<head>',\n '<meta charset=\"utf-8\">',\n '<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">',\n `<title>${escapeHtml(input.title)}</title>`,\n '<style>',\n ':root{font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,\"Segoe UI\",sans-serif;color:#172026;background:#f6f7f8}',\n 'body{margin:0;padding:32px}main{max-width:1180px;margin:0 auto;background:#fff;border:1px solid #d9dee3;border-radius:8px;padding:28px}',\n 'h1{font-size:30px;line-height:1.15;margin:0 0 8px}h2{font-size:18px;margin:28px 0 12px}p{line-height:1.55;color:#3d4952}.sub{color:#66737f;margin:0 0 20px}',\n '.summary{background:#eef6f8;border-left:4px solid #12829a;padding:14px 16px;margin:20px 0}.warnings{background:#fff7e8;border-left:4px solid #c87b00;padding:12px 16px}',\n '.table-wrap{overflow:auto;border:1px solid #dfe5ea;border-radius:8px}table{border-collapse:collapse;width:100%;font-size:13px}th,td{border-bottom:1px solid #edf0f2;padding:9px 10px;text-align:left;vertical-align:top}th{background:#f3f5f7;color:#31404c;position:sticky;top:0}tr:last-child td{border-bottom:0}',\n '</style>',\n '</head>',\n '<body><main>',\n `<h1>${escapeHtml(input.title)}</h1>`,\n input.subtitle ? `<p class=\"sub\">${escapeHtml(input.subtitle)}</p>` : '',\n `<div class=\"summary\">${escapeHtml(input.summary)}</div>`,\n warnings,\n sections,\n tables,\n '</main></body></html>',\n ].join('\\n')\n}\n\n","import { z } from 'zod'\nimport { renderWorkflowReport } from '../report-renderer.js'\nimport type { WorkflowDefinition, WorkflowRunContext, WorkflowRunSummary } from '../types.js'\nimport { DEFAULT_MAPS_PROXY_MODE } from '../../schemas.js'\n\nconst DirectoryWorkflowCliInputSchema = z.object({\n query: z.string().min(1),\n state: z.string().min(2).default('TN'),\n minPopulation: z.number().int().min(0).default(100_000),\n maxCities: z.number().int().min(1).max(100).default(25),\n maxResultsPerCity: z.number().int().min(1).max(50).default(20),\n concurrency: z.number().int().min(1).max(5).default(5),\n proxyMode: z.enum(['location', 'configured', 'none']).default(DEFAULT_MAPS_PROXY_MODE),\n saveCsv: z.boolean().default(true),\n})\n\ntype DirectoryWorkflowCliInput = z.infer<typeof DirectoryWorkflowCliInputSchema>\n\ninterface DirectoryBusiness {\n position: number\n name: string\n rating: string | null\n reviewCount: string | null\n category: string | null\n address: string | null\n phone: string | null\n websiteUrl: string | null\n placeUrl: string\n cid: string | null\n cidDecimal: string | null\n}\n\ninterface DirectoryCity {\n city: string\n state: string\n location: string\n population: number\n status: 'ok' | 'empty' | 'failed'\n error: string | null\n resultCount: number\n results: DirectoryBusiness[]\n}\n\nexport interface DirectoryWorkflowApiResult {\n query: string\n state: string\n selectedCityCount: number\n totalResultCount: number\n warnings: string[]\n csvPath: string | null\n cities: DirectoryCity[]\n}\n\nexport function directoryRows(result: DirectoryWorkflowApiResult): Array<Record<string, unknown>> {\n const rows: Array<Record<string, unknown>> = []\n for (const city of result.cities) {\n if (!city.results.length) {\n rows.push({\n source_query: result.query,\n source_location: city.location,\n city: city.city,\n state: city.state,\n population: city.population,\n result_position: null,\n business_name: null,\n review_stars: null,\n review_count: null,\n category: null,\n address: null,\n phone: null,\n website_url: null,\n place_url: null,\n cid: null,\n cid_decimal: null,\n result_status: city.status,\n error: city.error,\n })\n continue\n }\n for (const business of city.results) {\n rows.push({\n source_query: result.query,\n source_location: city.location,\n city: city.city,\n state: city.state,\n population: city.population,\n result_position: business.position,\n business_name: business.name,\n review_stars: business.rating,\n review_count: business.reviewCount,\n category: business.category,\n address: business.address,\n phone: business.phone,\n website_url: business.websiteUrl,\n place_url: business.placeUrl,\n cid: business.cid,\n cid_decimal: business.cidDecimal,\n result_status: city.status,\n error: city.error,\n })\n }\n }\n return rows\n}\n\nexport const DIRECTORY_CSV_HEADERS = [\n 'source_query',\n 'source_location',\n 'city',\n 'state',\n 'population',\n 'result_position',\n 'business_name',\n 'review_stars',\n 'review_count',\n 'category',\n 'address',\n 'phone',\n 'website_url',\n 'place_url',\n 'cid',\n 'cid_decimal',\n 'result_status',\n 'error',\n]\n\nexport const directoryWorkflowDefinition: WorkflowDefinition<DirectoryWorkflowCliInput> = {\n id: 'directory',\n title: 'Directory Workflow',\n description: 'Select city markets and export Google Maps business candidates.',\n inputSchema: DirectoryWorkflowCliInputSchema,\n async run(input: DirectoryWorkflowCliInput, ctx: WorkflowRunContext): Promise<WorkflowRunSummary> {\n await ctx.artifacts.writeManifest('running', {}, [], [])\n const result = await ctx.client.post<DirectoryWorkflowApiResult>('/directory/run', input as Record<string, unknown>, 900_000)\n await ctx.artifacts.writeJson('Directory evidence', 'evidence.json', result)\n const rows = directoryRows(result)\n await ctx.artifacts.writeCsv('Directory CSV', 'exports/directory.csv', DIRECTORY_CSV_HEADERS, rows)\n\n const cityRows = result.cities.map(city => ({\n city: city.city,\n state: city.state,\n population: city.population,\n status: city.status,\n result_count: city.resultCount,\n error: city.error ?? '',\n }))\n const topRows = rows\n .filter(row => row.business_name)\n .slice(0, 100)\n .map(row => ({\n city: row.city,\n position: row.result_position,\n business: row.business_name,\n rating: row.review_stars,\n reviews: row.review_count,\n category: row.category,\n website: row.website_url,\n }))\n\n const summary = `${result.selectedCityCount} cities processed with ${result.totalResultCount} Maps results.`\n await ctx.artifacts.writeText('Summary', 'summary.md', `# Directory Workflow\\n\\n${summary}\\n`)\n const reportPath = await ctx.artifacts.writeHtml('HTML report', 'report.html', renderWorkflowReport({\n title: 'Directory Workflow',\n subtitle: `${input.query} · ${input.state}`,\n summary,\n warnings: result.warnings,\n tables: [\n { title: 'Cities', columns: ['city', 'state', 'population', 'status', 'result_count', 'error'], rows: cityRows },\n { title: 'Top Results', columns: ['city', 'position', 'business', 'rating', 'reviews', 'category', 'website'], rows: topRows },\n ],\n }))\n const status = result.cities.some(city => city.status === 'failed') ? 'partial' : 'succeeded'\n const counts = { cities: result.selectedCityCount, results: result.totalResultCount, rows: rows.length }\n await ctx.artifacts.writeManifest(status, counts, result.warnings, [])\n return { title: 'Directory Workflow', summary, status, counts, warnings: result.warnings, errors: [], reportPath }\n },\n}\n","import { z } from 'zod'\n\nexport const DEFAULT_PROXY_MODE = 'none' as const\nexport const DEFAULT_MAPS_PROXY_MODE = 'location' as const\n\nexport const HarvestOptionsSchema = z.object({\n query: z.string().min(1),\n location: z.string().optional(),\n gl: z.string().length(2).default('us'),\n hl: z.string().length(2).default('en'),\n device: z.enum(['desktop', 'mobile']).default('desktop'),\n proxyMode: z.enum(['location', 'configured', 'none']).default(DEFAULT_PROXY_MODE),\n proxyZip: z.string().regex(/^\\d{5}$/).optional(),\n debug: z.boolean().default(false),\n depth: z.number().int().min(1).max(30).default(3),\n maxQuestions: z.number().int().min(1).max(1000).default(100),\n headless: z.boolean().default(false),\n profileDir: z.string().optional(),\n proxy: z.string().url().optional(),\n kernelApiKey: z.string().optional(),\n kernelProxyId: z.string().optional(),\n kernelProxyResolution: z.unknown().optional(),\n outputDir: z.string().default('./paa-output'),\n format: z.enum(['json', 'csv', 'both']).default('both'),\n serpOnly: z.boolean().default(false),\n pages: z.number().int().min(1).max(2).default(1),\n softDeadlineMs: z.number().optional(),\n})\n\nexport const MapsPlaceOptionsSchema = z.object({\n businessName: z.string().min(1),\n location: z.string().min(1),\n gl: z.string().length(2).default('us'),\n hl: z.string().length(2).default('en'),\n includeReviews: z.boolean().default(false),\n maxReviews: z.number().int().min(1).max(500).default(50),\n includeServices: z.boolean().default(false),\n kernelApiKey: z.string().optional(),\n kernelProxyId: z.string().optional(),\n headless: z.boolean().default(true),\n})\n\nexport const MapsSearchOptionsSchema = z.object({\n query: z.string().min(1),\n location: z.string().optional(),\n gl: z.string().length(2).default('us'),\n hl: z.string().length(2).default('en'),\n maxResults: z.number().int().min(1).max(50).default(10),\n proxyMode: z.enum(['location', 'configured', 'none']).default(DEFAULT_MAPS_PROXY_MODE),\n proxyZip: z.string().regex(/^\\d{5}$/).optional(),\n debug: z.boolean().default(false),\n kernelApiKey: z.string().optional(),\n kernelProxyId: z.string().optional(),\n kernelProxyResolution: z.unknown().optional(),\n headless: z.boolean().default(true),\n})\n\nexport const RawPAAItemSchema = z.object({\n question: z.string().min(1),\n answer: z.string().optional(),\n sourceTitle: z.string().optional(),\n sourceSite: z.string().optional(),\n sourceCite: z.string().optional(),\n})\n\nexport const RawMapsOverviewSchema = z.object({\n name: z.string().nullable(),\n rating: z.string().nullable(),\n reviewCount: z.string().nullable(),\n category: z.string().nullable(),\n address: z.string().nullable(),\n hoursSummary: z.string().nullable(),\n phone: z.string().nullable(),\n phoneDisplay: z.string().nullable(),\n website: z.string().nullable(),\n plusCode: z.string().nullable(),\n bookingUrl: z.string().nullable(),\n})\n\nexport const RawMapsHoursRowSchema = z.object({\n day: z.string(),\n hours: z.string(),\n})\n\nexport const RawMapsReviewStatsSchema = z.object({\n reviewHistogram: z.array(z.object({\n stars: z.number(),\n count: z.string(),\n })),\n reviewTopics: z.array(z.object({\n label: z.string(),\n count: z.string(),\n })),\n})\n\nexport const RawMapsReviewCardSchema = z.object({\n reviewId: z.string(),\n author: z.string().nullable(),\n stars: z.string().nullable(),\n date: z.string().nullable(),\n text: z.string().nullable(),\n ownerResponse: z.string().nullable(),\n})\n\nexport const RawMapsAboutAttributeSchema = z.object({\n section: z.string(),\n attribute: z.string(),\n})\n","import { z } from 'zod'\nimport { renderWorkflowReport } from '../report-renderer.js'\nimport type { WorkflowDefinition, WorkflowRunContext, WorkflowRunSummary } from '../types.js'\nimport { DEFAULT_MAPS_PROXY_MODE } from '../../schemas.js'\n\nconst GetLeadsInputSchema = z.object({\n query: z.string().min(1).describe('Business category, niche, or keyword to search on Google Maps, e.g. \"roofers\", \"med spas\", \"dentists\". Do not include the city here.'),\n location: z.string().min(1).describe('City / market to search, e.g. \"Houston, TX\" or \"Austin, Texas\".'),\n maxResults: z.number().int().min(1).max(50).default(25).describe('How many Maps businesses to collect for the market. Maximum 50.'),\n enrichWebsites: z.boolean().default(true).describe('Visit each business website (home + contact pages) to harvest email and social links. Uses the proxy/browser-backed extractor so blocked sites still resolve.'),\n hydrateReviewCounts: z.boolean().default(true).describe('Deep-dive each profile to confirm the review count and booking URL that the Maps search list omits.'),\n concurrency: z.number().int().min(1).max(4).default(3).describe('How many businesses to enrich in parallel. Keep low to respect per-account concurrency limits.'),\n proxyMode: z.enum(['location', 'configured', 'none']).default(DEFAULT_MAPS_PROXY_MODE).describe('Proxy targeting for the Maps search. location targets the market; none is for local debugging.'),\n})\n\ntype GetLeadsInput = z.infer<typeof GetLeadsInputSchema>\n\ninterface MapsSearchApiResult {\n query: string\n location: string | null\n searchQuery: string\n resultCount: number\n results: Array<{\n position: number\n name: string\n placeUrl: string\n cid: string | null\n cidDecimal: string | null\n rating: string | null\n reviewCount: string | null\n category: string | null\n address: string | null\n phone: string | null\n hoursStatus: string | null\n websiteUrl: string | null\n directionsUrl: string | null\n metadata: string[]\n }>\n}\n\ninterface MapsPlaceApiResult {\n name: string | null\n rating: string | null\n reviewCount: string | null\n category: string | null\n website: string | null\n phone?: string | null\n address?: string | null\n bookingUrl?: string | null\n}\n\ninterface ExtractUrlApiResult {\n title?: string | null\n bodyHtml?: string | null\n bodyMarkdown?: string | null\n}\n\ninterface LeadRow {\n position: number\n business_name: string\n review_stars: string\n review_count: string\n category: string\n address: string\n phone: string\n website: string\n email: string\n email_domain_match: string\n email_status: string\n socials: string\n booking_url: string\n place_url: string\n cid: string\n source_location: string\n [key: string]: string | number\n}\n\nconst LEADS_CSV_HEADERS = [\n 'position', 'business_name', 'review_stars', 'review_count', 'category', 'address', 'phone',\n 'website', 'email', 'email_domain_match', 'email_status', 'socials', 'booking_url', 'place_url', 'cid', 'source_location',\n]\n\nconst EMAIL_RE = /[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}/g\nconst MAILTO_RE = /mailto:([^\"'?>\\s]+)/gi\nconst SOCIAL_RE = /https?:\\/\\/(?:www\\.)?(?:facebook|instagram|linkedin|twitter|youtube|tiktok)\\.com\\/[^\\s\"'<>)]+/gi\nconst EMAIL_BAD = ['.png', '.jpg', '.jpeg', '.gif', '.svg', '.webp', '.ico', 'sentry', 'wix.com', 'wixpress', 'example.', 'godaddy', 'squarespace', 'schema.org', '@2x', 'u003e', 'core-js']\nconst EMAIL_PREFIX = ['info@', 'office@', 'contact@', 'sales@', 'hello@', 'admin@', 'service@', 'support@']\nconst SOCIAL_SKIP = ['/sharer', '/share?', '/intent/', 'plugins/', '/dialog/', 'platform.', 'badge', 'developers.']\n\nasync function mapLimit<T, R>(items: T[], limit: number, fn: (item: T, index: number) => Promise<R>): Promise<R[]> {\n const out: R[] = new Array(items.length)\n let next = 0\n async function worker(): Promise<void> {\n while (next < items.length) {\n const index = next\n next += 1\n out[index] = await fn(items[index], index)\n }\n }\n await Promise.all(Array.from({ length: Math.min(limit, items.length) }, () => worker()))\n return out\n}\n\nfunction hostRoot(url: string): string {\n try {\n return new URL(url).hostname.replace(/^www\\./, '').split('.')[0].toLowerCase()\n } catch {\n return ''\n }\n}\n\nfunction cleanEmails(raw: string[]): string[] {\n const out = new Set<string>()\n for (const value of raw) {\n const email = value.trim().toLowerCase().replace(/\\.$/, '')\n if (email.split('@').length !== 2) continue\n if (email.length > 60) continue\n if (EMAIL_BAD.some(bad => email.includes(bad))) continue\n out.add(email)\n }\n return [...out]\n}\n\nfunction pickEmail(emails: string[], host: string): string {\n if (!emails.length) return ''\n const root = hostRoot(host)\n for (const prefix of EMAIL_PREFIX) {\n const hit = emails.find(e => e.startsWith(prefix) && root && e.split('@')[1].includes(root))\n if (hit) return hit\n }\n const domainHit = emails.find(e => root && e.split('@')[1].includes(root))\n if (domainHit) return domainHit\n for (const prefix of EMAIL_PREFIX) {\n const hit = emails.find(e => e.startsWith(prefix))\n if (hit) return hit\n }\n return emails[0]\n}\n\nfunction parseContacts(html: string): { emails: string[]; socials: string[] } {\n const mailtos = [...html.matchAll(MAILTO_RE)].map(m => decodeURIComponent(m[1]).split('?')[0])\n const inline = html.match(EMAIL_RE) ?? []\n const emails = cleanEmails([...mailtos, ...inline])\n const socials = [...new Set((html.match(SOCIAL_RE) ?? [])\n .map(s => s.replace(/[)\"'<>]+$/, ''))\n .filter(s => !SOCIAL_SKIP.some(skip => s.toLowerCase().includes(skip))))]\n .slice(0, 5)\n return { emails, socials }\n}\n\nfunction buildAttemptUrls(website: string): string[] {\n const urls = new Set<string>()\n urls.add(website)\n try {\n const origin = new URL(website).origin\n urls.add(`${origin}/contact`)\n urls.add(`${origin}/contact-us`)\n } catch {\n return [...urls]\n }\n return [...urls].slice(0, 3)\n}\n\nexport const getLeadsWorkflowDefinition: WorkflowDefinition<GetLeadsInput> = {\n id: 'get-leads',\n title: 'Get Leads',\n description: 'Build an outreach-ready local lead list: Google Maps search for a niche in a market, confirm review counts + booking URLs, then visit each business website (home + contact) to harvest email and social links, with proxy/browser-backed extraction so blocked sites still resolve. Saves a leads CSV.',\n inputSchema: GetLeadsInputSchema,\n async run(input: GetLeadsInput, ctx: WorkflowRunContext): Promise<WorkflowRunSummary> {\n await ctx.artifacts.writeManifest('running', {}, [], [])\n const warnings: string[] = []\n const errors: string[] = []\n\n const search = await ctx.client.post<MapsSearchApiResult>('/maps/search', {\n query: input.query,\n location: input.location,\n maxResults: input.maxResults,\n proxyMode: input.proxyMode,\n }, 180_000)\n await ctx.artifacts.writeJson('Maps search raw', 'raw/maps-search.json', search)\n\n const seen = new Set<string>()\n const deduped = search.results.filter(result => {\n const key = result.cid ?? result.placeUrl ?? result.name.toLowerCase()\n if (seen.has(key)) return false\n seen.add(key)\n return true\n })\n\n const rows = await mapLimit(deduped, input.concurrency, async (result): Promise<LeadRow> => {\n let reviewCount = result.reviewCount ?? ''\n let bookingUrl = ''\n let website = result.websiteUrl ?? ''\n\n if (input.hydrateReviewCounts) {\n try {\n const place = await ctx.client.post<MapsPlaceApiResult>('/maps/place', {\n businessName: result.name,\n location: input.location,\n includeReviews: false,\n }, 180_000)\n reviewCount = place.reviewCount ?? reviewCount\n bookingUrl = place.bookingUrl ?? ''\n website = website || (place.website ?? '')\n } catch (err) {\n warnings.push(`Review hydration failed for ${result.name}: ${err instanceof Error ? err.message : String(err)}`)\n }\n }\n\n let email = ''\n let socials: string[] = []\n let emailStatus = website ? 'no email found' : 'no website'\n let domainMatch = ''\n\n if (input.enrichWebsites && website) {\n const attempts = buildAttemptUrls(website)\n let reached = false\n const allEmails: string[] = []\n const allSocials = new Set<string>()\n for (const attemptUrl of attempts) {\n try {\n const page = await ctx.client.post<ExtractUrlApiResult>('/extract-url', { url: attemptUrl }, 120_000)\n reached = true\n const parsed = parseContacts(page.bodyHtml ?? page.bodyMarkdown ?? '')\n allEmails.push(...parsed.emails)\n parsed.socials.forEach(s => allSocials.add(s))\n if (parsed.emails.length) break\n } catch {\n continue\n }\n }\n socials = [...allSocials].slice(0, 5)\n email = pickEmail([...new Set(allEmails)], website)\n if (email) {\n domainMatch = hostRoot(website) && email.split('@')[1].includes(hostRoot(website)) ? 'yes' : 'NO-verify'\n emailStatus = domainMatch === 'yes' ? 'ok' : 'ok (off-domain — verify)'\n } else if (!reached) {\n emailStatus = 'site unreachable'\n } else if (socials.length) {\n emailStatus = 'form/social only'\n }\n }\n\n return {\n position: result.position,\n business_name: result.name,\n review_stars: result.rating ?? '',\n review_count: reviewCount,\n category: result.category ?? '',\n address: result.address ?? '',\n phone: result.phone ?? '',\n website,\n email,\n email_domain_match: domainMatch,\n email_status: emailStatus,\n socials: socials.join(' ; '),\n booking_url: bookingUrl,\n place_url: result.placeUrl,\n cid: result.cid ?? '',\n source_location: input.location,\n }\n })\n\n await ctx.artifacts.writeCsv('Leads CSV', 'exports/leads.csv', LEADS_CSV_HEADERS, rows)\n await ctx.artifacts.writeJson('Leads evidence', 'evidence.json', { input, search: { query: search.searchQuery, resultCount: search.resultCount }, rows })\n\n const withEmail = rows.filter(r => r.email).length\n const domainMatched = rows.filter(r => r.email_domain_match === 'yes').length\n const withReviewCount = rows.filter(r => r.review_count).length\n const withSocials = rows.filter(r => r.socials).length\n const withWebsite = rows.filter(r => r.website).length\n\n const summary = `${rows.length} ${input.query} in ${input.location}: ${withEmail} emails (${domainMatched} domain-matched), ${withReviewCount} review counts, ${withSocials} with socials.`\n await ctx.artifacts.writeText('Summary', 'summary.md', `# Get Leads\\n\\n${summary}\\n`)\n await ctx.artifacts.writeText('Agent tasks', 'tasks.md', [\n '# Get Leads — next steps',\n '',\n '- [ ] Verify deliverability of the harvested emails before outreach (MX/SMTP check).',\n '- [ ] For \"form/social only\" rows, use the website contact form or the captured social profile.',\n '- [ ] Treat \"off-domain — verify\" emails with care; they may belong to a web developer or parent brand.',\n '- [ ] Respect CAN-SPAM / GDPR — scraped contact data is not consent to email.',\n ].join('\\n'))\n\n const reportPath = await ctx.artifacts.writeHtml('HTML report', 'report.html', renderWorkflowReport({\n title: 'Get Leads',\n subtitle: `${input.query} · ${input.location}`,\n summary,\n warnings,\n tables: [\n {\n title: 'Leads',\n columns: ['position', 'business_name', 'review_stars', 'review_count', 'phone', 'website', 'email', 'email_status', 'socials', 'booking_url'],\n rows,\n },\n ],\n }))\n\n const status: WorkflowRunSummary['status'] = errors.length ? 'failed' : warnings.length ? 'partial' : 'succeeded'\n const counts = {\n businesses: rows.length,\n withWebsite,\n emails: withEmail,\n domainMatchedEmails: domainMatched,\n reviewCounts: withReviewCount,\n withSocials,\n }\n await ctx.artifacts.writeManifest(status, counts, warnings, errors)\n return { title: 'Get Leads', summary, status, counts, warnings, errors, reportPath }\n },\n}\n","import { z } from 'zod'\nimport { renderWorkflowReport } from '../report-renderer.js'\nimport type { WorkflowDefinition, WorkflowRunContext, WorkflowRunSummary } from '../types.js'\nimport { DIRECTORY_CSV_HEADERS, directoryRows, type DirectoryWorkflowApiResult } from './directory.js'\nimport { DEFAULT_MAPS_PROXY_MODE } from '../../schemas.js'\n\nconst LocalCompetitiveAuditInputSchema = z.object({\n query: z.string().min(1),\n state: z.string().min(2).default('TN'),\n minPopulation: z.number().int().min(0).default(100_000),\n maxCities: z.number().int().min(1).max(100).default(25),\n maxResultsPerCity: z.number().int().min(1).max(50).default(20),\n hydrateTop: z.number().int().min(0).max(10).default(5),\n maxReviews: z.number().int().min(0).max(500).default(50),\n concurrency: z.number().int().min(1).max(5).default(5),\n proxyMode: z.enum(['location', 'configured', 'none']).default(DEFAULT_MAPS_PROXY_MODE),\n returnPartial: z.boolean().default(true),\n})\n\ntype LocalCompetitiveAuditInput = z.infer<typeof LocalCompetitiveAuditInputSchema>\n\ninterface MapsPlaceIntelResult {\n name: string | null\n rating: string | null\n reviewCount: string | null\n category: string | null\n website: string | null\n reviewsStatus: string\n reviewHistogram: Array<{ stars: number; count: string }>\n reviewTopics: Array<{ label: string; count: string }>\n aboutAttributes: Array<{ section: string; attribute: string }>\n reviews: Array<{ stars: string | null; text: string | null; ownerResponse: string | null }>\n}\n\nasync function mapLimit<T, R>(items: T[], limit: number, fn: (item: T, index: number) => Promise<R>): Promise<R[]> {\n const out: R[] = new Array(items.length)\n let next = 0\n async function worker(): Promise<void> {\n while (next < items.length) {\n const index = next\n next += 1\n out[index] = await fn(items[index], index)\n }\n }\n await Promise.all(Array.from({ length: Math.min(limit, items.length) }, () => worker()))\n return out\n}\n\nfunction numberFrom(value: unknown): number | null {\n if (value === null || value === undefined || value === '') return null\n const parsed = Number(String(value).replace(/[^\\d.]/g, ''))\n return Number.isFinite(parsed) ? parsed : null\n}\n\nfunction median(values: Array<number | null>): number | null {\n const nums = values.filter((v): v is number => v !== null).sort((a, b) => a - b)\n if (!nums.length) return null\n return nums[Math.floor(nums.length / 2)] ?? null\n}\n\nfunction termsFrom(texts: string[]): string {\n const stop = new Set(['the', 'and', 'for', 'with', 'that', 'this', 'was', 'were', 'are', 'you', 'our', 'they', 'had', 'have', 'not', 'but', 'from', 'very', 'great', 'good'])\n const counts = new Map<string, number>()\n for (const text of texts) {\n for (const token of text.toLowerCase().replace(/[^a-z0-9\\s]/g, ' ').split(/\\s+/)) {\n if (token.length < 4 || stop.has(token)) continue\n counts.set(token, (counts.get(token) ?? 0) + 1)\n }\n }\n return [...counts.entries()].sort((a, b) => b[1] - a[1]).slice(0, 8).map(([term, count]) => `${term} (${count})`).join('; ')\n}\n\nexport const localCompetitiveAuditWorkflowDefinition: WorkflowDefinition<LocalCompetitiveAuditInput> = {\n id: 'local-competitive-audit',\n title: 'Local Competitive Audit',\n description: 'Audit local Maps competitors, categories, review counts, and review themes across city markets.',\n inputSchema: LocalCompetitiveAuditInputSchema,\n async run(input: LocalCompetitiveAuditInput, ctx: WorkflowRunContext): Promise<WorkflowRunSummary> {\n await ctx.artifacts.writeManifest('running', {}, [], [])\n const warnings: string[] = []\n const errors: string[] = []\n const directory = await ctx.client.post<DirectoryWorkflowApiResult>('/directory/run', {\n query: input.query,\n state: input.state,\n minPopulation: input.minPopulation,\n maxCities: input.maxCities,\n maxResultsPerCity: input.maxResultsPerCity,\n concurrency: input.concurrency,\n proxyMode: input.proxyMode,\n saveCsv: true,\n }, 900_000)\n\n await ctx.artifacts.writeJson('Directory raw JSON', 'raw/directory-workflow.json', directory)\n const baseRows = directoryRows(directory)\n await ctx.artifacts.writeCsv('Base directory CSV', 'exports/directory.csv', DIRECTORY_CSV_HEADERS, baseRows)\n\n const selected = directory.cities.flatMap(city =>\n city.results.slice(0, input.hydrateTop).map(result => ({ city, result })),\n )\n const seen = new Set<string>()\n const deduped = selected.filter(({ city, result }) => {\n const key = result.cid ?? result.placeUrl ?? `${city.location}:${result.name.toLowerCase()}`\n if (seen.has(key)) return false\n seen.add(key)\n return true\n })\n\n const hydrated = await mapLimit(deduped, 3, async ({ city, result }, index) => {\n try {\n const detail = await ctx.client.post<MapsPlaceIntelResult>('/maps/place', {\n businessName: result.name,\n location: city.location,\n includeReviews: input.maxReviews > 0,\n maxReviews: Math.max(1, input.maxReviews),\n }, 180_000)\n await ctx.artifacts.writeJson(`${result.name} profile`, `raw/maps-place-intel/${index + 1}-${result.name.toLowerCase().replace(/[^a-z0-9]+/g, '-')}.json`, detail)\n return { city, result, detail, error: null as string | null }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n warnings.push(`Profile hydration failed for ${result.name} (${city.location}): ${message}`)\n return { city, result, detail: null, error: message }\n }\n })\n\n const competitorRows = hydrated.map(({ city, result, detail, error }) => {\n const reviews = detail?.reviews ?? []\n const ownerResponses = reviews.filter(r => r.ownerResponse).length\n return {\n city: city.city,\n state: city.state,\n source_location: city.location,\n result_position: result.position,\n business_name: result.name,\n category: detail?.category ?? result.category,\n review_stars: detail?.rating ?? result.rating,\n review_count: detail?.reviewCount ?? result.reviewCount,\n phone: result.phone,\n website_url: detail?.website ?? result.websiteUrl,\n place_url: result.placeUrl,\n cid: result.cid,\n cid_decimal: result.cidDecimal,\n hydrated: detail ? 'true' : 'false',\n reviews_status: detail?.reviewsStatus ?? '',\n review_topics: (detail?.reviewTopics ?? []).map(t => `${t.label} (${t.count})`).join('; '),\n owner_response_rate: reviews.length ? (ownerResponses / reviews.length).toFixed(2) : '',\n error: error ?? '',\n }\n })\n\n const reviewInsightRows = hydrated.map(({ city, result, detail }) => {\n const reviews = detail?.reviews ?? []\n const positive = reviews.filter(r => Number(r.stars) >= 5 && r.text).map(r => r.text!)\n const negative = reviews.filter(r => Number(r.stars) > 0 && Number(r.stars) <= 3 && r.text).map(r => r.text!)\n return {\n city: city.city,\n business_name: result.name,\n cid: result.cid,\n review_count: detail?.reviewCount ?? result.reviewCount,\n average_rating: detail?.rating ?? result.rating,\n topics: (detail?.reviewTopics ?? []).map(t => `${t.label} (${t.count})`).join('; '),\n praise_terms: termsFrom(positive),\n complaint_terms: termsFrom(negative),\n positive_sample: positive[0]?.slice(0, 280) ?? '',\n negative_sample: negative[0]?.slice(0, 280) ?? '',\n }\n })\n\n const citySummaryRows = directory.cities.map(city => {\n const resultReviewCounts = city.results.map(r => numberFrom(r.reviewCount))\n const resultRatings = city.results.map(r => numberFrom(r.rating))\n const topThreeReviews = city.results.slice(0, 3).map(r => numberFrom(r.reviewCount)).filter((v): v is number => v !== null)\n const categories = new Map<string, number>()\n for (const result of city.results) {\n if (!result.category) continue\n categories.set(result.category, (categories.get(result.category) ?? 0) + 1)\n }\n const medReviews = median(resultReviewCounts)\n const medRating = median(resultRatings)\n const topThreeAvg = topThreeReviews.length ? Math.round(topThreeReviews.reduce((a, b) => a + b, 0) / topThreeReviews.length) : null\n const difficulty = Math.min(100, Math.round((topThreeAvg ?? 0) / 20 + (medRating ?? 0) * 10 + city.results.filter(r => r.websiteUrl).length))\n const opportunity = Math.max(0, 100 - difficulty)\n return {\n city: city.city,\n state: city.state,\n population: city.population,\n result_count: city.resultCount,\n median_review_count: medReviews ?? '',\n median_rating: medRating ?? '',\n top_three_average_review_count: topThreeAvg ?? '',\n top_categories: [...categories.entries()].sort((a, b) => b[1] - a[1]).slice(0, 5).map(([cat, count]) => `${cat} (${count})`).join('; '),\n opportunity_score: opportunity,\n difficulty_score: difficulty,\n }\n })\n\n await ctx.artifacts.writeCsv('Competitors CSV', 'competitors.csv', ['city', 'state', 'source_location', 'result_position', 'business_name', 'category', 'review_stars', 'review_count', 'phone', 'website_url', 'place_url', 'cid', 'cid_decimal', 'hydrated', 'reviews_status', 'review_topics', 'owner_response_rate', 'error'], competitorRows)\n await ctx.artifacts.writeCsv('Review insights CSV', 'review-insights.csv', ['city', 'business_name', 'cid', 'review_count', 'average_rating', 'topics', 'praise_terms', 'complaint_terms', 'positive_sample', 'negative_sample'], reviewInsightRows)\n await ctx.artifacts.writeCsv('City summary CSV', 'city-summary.csv', ['city', 'state', 'population', 'result_count', 'median_review_count', 'median_rating', 'top_three_average_review_count', 'top_categories', 'opportunity_score', 'difficulty_score'], citySummaryRows)\n await ctx.artifacts.writeJson('Audit evidence', 'evidence.json', { input, directory, hydrated, citySummaryRows, competitorRows, reviewInsightRows })\n await ctx.artifacts.writeText('Agent tasks', 'tasks.md', [\n '# Local Competitive Audit Tasks',\n '',\n '- [ ] Review city opportunity and difficulty scores as heuristics, not absolute truth.',\n '- [ ] Use review topics and samples as customer-language evidence.',\n '- [ ] Compare target GBP category, review count, and website quality against top competitors.',\n '- [ ] Identify cities with low review-count leaders and weak website coverage.',\n ].join('\\n'))\n\n const summary = `${directory.selectedCityCount} cities, ${directory.totalResultCount} Maps results, ${hydrated.filter(h => h.detail).length} hydrated profiles.`\n await ctx.artifacts.writeText('Summary', 'summary.md', `# Local Competitive Audit\\n\\n${summary}\\n`)\n const reportPath = await ctx.artifacts.writeHtml('HTML report', 'report.html', renderWorkflowReport({\n title: 'Local Competitive Audit',\n subtitle: `${input.query} · ${input.state}`,\n summary,\n warnings,\n tables: [\n { title: 'City Opportunity', columns: ['city', 'state', 'population', 'result_count', 'median_review_count', 'median_rating', 'top_three_average_review_count', 'top_categories', 'opportunity_score', 'difficulty_score'], rows: citySummaryRows },\n { title: 'Hydrated Competitors', columns: ['city', 'result_position', 'business_name', 'category', 'review_stars', 'review_count', 'hydrated', 'review_topics'], rows: competitorRows.slice(0, 100) },\n { title: 'Review Insights', columns: ['city', 'business_name', 'topics', 'praise_terms', 'complaint_terms'], rows: reviewInsightRows.slice(0, 100) },\n ],\n }))\n\n const status = warnings.length || directory.cities.some(city => city.status === 'failed') ? 'partial' : 'succeeded'\n const counts = { cities: directory.selectedCityCount, mapsResults: directory.totalResultCount, hydratedProfiles: hydrated.filter(h => h.detail).length }\n await ctx.artifacts.writeManifest(status, counts, warnings, errors)\n return { title: 'Local Competitive Audit', summary, status, counts, warnings, errors, reportPath }\n },\n}\n","import { z } from 'zod'\nimport { renderWorkflowReport } from '../report-renderer.js'\nimport type { WorkflowDefinition, WorkflowRunContext, WorkflowRunSummary } from '../types.js'\nimport { DIRECTORY_CSV_HEADERS, directoryRows, type DirectoryWorkflowApiResult } from './directory.js'\nimport {\n classifySentence,\n domainFromUrl,\n mapLimit,\n median,\n normalizeDomain,\n numberFrom,\n pageSummaryRow,\n questionRows,\n sourceDomainRows,\n splitSentences,\n textTerms,\n type ExtractUrlResult,\n type HarvestLike,\n type MapsSearchBusinessLike,\n type MapsSearchResultLike,\n type OrganicResult,\n} from './seo-workflow-utils.js'\nimport { DEFAULT_MAPS_PROXY_MODE } from '../../schemas.js'\n\nconst ProxyModeSchema = z.enum(['location', 'configured', 'none'])\n\nconst MapComparisonInputSchema = z.object({\n query: z.string().min(1),\n location: z.string().optional(),\n state: z.string().optional(),\n minPopulation: z.number().int().min(0).default(100_000),\n maxCities: z.number().int().min(1).max(100).default(5),\n maxResultsPerCity: z.number().int().min(1).max(50).default(20),\n hydrateTop: z.number().int().min(0).max(10).default(5),\n maxReviews: z.number().int().min(0).max(500).default(25),\n concurrency: z.number().int().min(1).max(5).default(5),\n proxyMode: ProxyModeSchema.default(DEFAULT_MAPS_PROXY_MODE),\n returnPartial: z.boolean().default(true),\n}).refine(input => input.location || input.state, {\n message: 'Either location or state is required for map-comparison',\n})\n\nconst SerpComparisonInputSchema = z.object({\n keyword: z.string().min(1),\n domain: z.string().optional(),\n url: z.string().url().optional(),\n location: z.string().optional(),\n maxResults: z.number().int().min(1).max(20).default(10),\n maxQuestions: z.number().int().min(1).max(200).default(40),\n extractTop: z.number().int().min(0).max(10).default(5),\n includePaa: z.boolean().default(true),\n includeAiOverview: z.boolean().default(true),\n returnPartial: z.boolean().default(true),\n})\n\nconst PaaExpansionBriefInputSchema = z.object({\n keyword: z.string().min(1),\n location: z.string().optional(),\n maxQuestions: z.number().int().min(1).max(300).default(80),\n depth: z.number().int().min(1).max(6).default(3),\n returnPartial: z.boolean().default(true),\n})\n\nconst AiOverviewLanguageInputSchema = z.object({\n keyword: z.string().min(1),\n domain: z.string().optional(),\n url: z.string().url().optional(),\n location: z.string().optional(),\n maxQuestions: z.number().int().min(1).max(200).default(40),\n extractTop: z.number().int().min(0).max(8).default(3),\n returnPartial: z.boolean().default(true),\n})\n\ntype MapComparisonInput = z.infer<typeof MapComparisonInputSchema>\ntype SerpComparisonInput = z.infer<typeof SerpComparisonInputSchema>\ntype PaaExpansionBriefInput = z.infer<typeof PaaExpansionBriefInputSchema>\ntype AiOverviewLanguageInput = z.infer<typeof AiOverviewLanguageInputSchema>\n\ninterface MapsPlaceIntelResult {\n name?: string | null\n rating?: string | null\n reviewCount?: string | null\n category?: string | null\n website?: string | null\n reviewsStatus?: string\n reviewTopics?: Array<{ label: string; count: string }>\n aboutAttributes?: Array<{ section: string; attribute: string }>\n reviews?: Array<{ stars: string | null; text: string | null; ownerResponse: string | null }>\n}\n\nfunction businessRowsFromMaps(location: string, query: string, results: MapsSearchBusinessLike[]): Array<Record<string, unknown>> {\n return results.map(result => ({\n source_query: query,\n source_location: location,\n city: location.split(',')[0]?.trim() ?? location,\n state: location.split(',')[1]?.trim() ?? '',\n population: '',\n result_position: result.position,\n business_name: result.name,\n review_stars: result.rating ?? '',\n review_count: result.reviewCount ?? '',\n category: result.category ?? '',\n address: result.address ?? '',\n phone: result.phone ?? '',\n website_url: result.websiteUrl ?? '',\n place_url: result.placeUrl ?? '',\n cid: result.cid ?? '',\n cid_decimal: result.cidDecimal ?? '',\n result_status: 'ok',\n error: '',\n }))\n}\n\nfunction marketRows(rows: Array<Record<string, unknown>>): Array<Record<string, unknown>> {\n const byLocation = new Map<string, Array<Record<string, unknown>>>()\n for (const row of rows) {\n const key = String(row.source_location ?? row.location ?? '')\n if (!key) continue\n const list = byLocation.get(key) ?? []\n list.push(row)\n byLocation.set(key, list)\n }\n return [...byLocation.entries()].map(([location, list]) => {\n const counts = list.map(row => numberFrom(row.review_count))\n const ratings = list.map(row => numberFrom(row.review_stars))\n const topThree = list.slice(0, 3).map(row => numberFrom(row.review_count)).filter((v): v is number => v !== null)\n const categories = new Map<string, number>()\n for (const row of list) {\n const category = String(row.category ?? '')\n if (category) categories.set(category, (categories.get(category) ?? 0) + 1)\n }\n return {\n source_location: location,\n result_count: list.filter(row => row.business_name).length,\n median_review_count: median(counts) ?? '',\n median_rating: median(ratings) ?? '',\n top_three_average_review_count: topThree.length ? Math.round(topThree.reduce((a, b) => a + b, 0) / topThree.length) : '',\n top_categories: [...categories.entries()].sort((a, b) => b[1] - a[1]).slice(0, 5).map(([cat, count]) => `${cat} (${count})`).join('; '),\n websites_present: list.filter(row => row.website_url).length,\n }\n })\n}\n\nfunction comparisonRows(rows: Array<Record<string, unknown>>): Array<Record<string, unknown>> {\n const benchmarkByLocation = new Map<string, number>()\n for (const market of marketRows(rows)) {\n benchmarkByLocation.set(String(market.source_location), numberFrom(market.top_three_average_review_count) ?? 0)\n }\n return rows\n .filter(row => row.business_name)\n .map(row => {\n const reviews = numberFrom(row.review_count) ?? 0\n const benchmark = benchmarkByLocation.get(String(row.source_location)) ?? 0\n const websiteMissing = !row.website_url\n const rank = numberFrom(row.result_position) ?? 999\n return {\n source_location: row.source_location,\n result_position: row.result_position,\n business_name: row.business_name,\n category: row.category,\n review_stars: row.review_stars,\n review_count: row.review_count,\n review_gap_to_top3_average: benchmark ? Math.max(0, benchmark - reviews) : '',\n website_url: row.website_url,\n place_url: row.place_url,\n comparison_note: rank <= 3 ? 'visible leader' : websiteMissing ? 'ranking without website' : reviews < benchmark ? 'review-light competitor' : 'visible competitor',\n }\n })\n}\n\nfunction organicRows(serp: HarvestLike | null, targetDomain: string | null): Array<Record<string, unknown>> {\n return (serp?.organicResults ?? []).map(result => {\n const url = result.url ?? ''\n const domain = normalizeDomain(result.domain ?? '') ?? domainFromUrl(url)\n return {\n position: result.position ?? '',\n title: result.title ?? '',\n url,\n domain,\n snippet: result.snippet ?? '',\n is_target: targetDomain ? domain === targetDomain : false,\n }\n })\n}\n\nfunction pageGapRows(targetPage: ExtractUrlResult | null, competitorPages: Array<{ source: OrganicResult; page: ExtractUrlResult }>): Array<Record<string, unknown>> {\n const targetHeadingText = new Set((targetPage?.headings ?? []).map(h => h.text.toLowerCase().replace(/[^a-z0-9\\s]/g, ' ').trim()))\n const targetTerms = new Set((targetPage?.headings ?? []).flatMap(h => h.text.toLowerCase().replace(/[^a-z0-9\\s]/g, ' ').split(/\\s+/).filter(Boolean)))\n const rows: Array<Record<string, unknown>> = []\n for (const { source, page } of competitorPages) {\n for (const heading of page.headings ?? []) {\n if (heading.level > 3 || !heading.text) continue\n const normalized = heading.text.toLowerCase().replace(/[^a-z0-9\\s]/g, ' ').trim()\n const terms = normalized.split(/\\s+/).filter(term => term.length > 3)\n const overlap = terms.filter(term => targetTerms.has(term)).length\n const covered = targetHeadingText.has(normalized) || overlap >= Math.max(2, Math.ceil(terms.length / 2))\n if (covered && targetPage) continue\n rows.push({\n source_position: source.position ?? '',\n source_domain: normalizeDomain(source.domain ?? '') ?? domainFromUrl(source.url),\n source_url: source.url ?? '',\n heading_level: heading.level,\n competitor_heading: heading.text,\n target_coverage: targetPage ? 'not found in target headings' : 'no target page extracted',\n terms: textTerms(heading.text, 6),\n })\n }\n }\n return rows.slice(0, 150)\n}\n\nasync function extractPages(ctx: WorkflowRunContext, sources: OrganicResult[], warnings: string[], labelPrefix: string): Promise<Array<{ source: OrganicResult; page: ExtractUrlResult }>> {\n return mapLimit(sources.filter(source => source.url), 2, async (source, index) => {\n try {\n const page = await ctx.client.post<ExtractUrlResult>('/extract-url', { url: source.url }, 180_000)\n await ctx.artifacts.writeJson(`${labelPrefix} ${index + 1}`, `raw/extract-url/${labelPrefix.toLowerCase()}-${index + 1}.json`, page)\n return { source, page }\n } catch (err) {\n warnings.push(`Page extraction failed for ${source.url}: ${err instanceof Error ? err.message : String(err)}`)\n return null\n }\n }).then(items => items.filter((item): item is { source: OrganicResult; page: ExtractUrlResult } => item !== null))\n}\n\nexport const mapComparisonWorkflowDefinition: WorkflowDefinition<MapComparisonInput> = {\n id: 'map-comparison',\n title: 'Maps Comparison',\n description: 'Compare Google Maps competitors by rank, reviews, stars, categories, websites, and profile/review signals.',\n inputSchema: MapComparisonInputSchema,\n async run(input: MapComparisonInput, ctx: WorkflowRunContext): Promise<WorkflowRunSummary> {\n await ctx.artifacts.writeManifest('running', {}, [], [])\n const warnings: string[] = []\n let rows: Array<Record<string, unknown>>\n let directory: DirectoryWorkflowApiResult | null = null\n let mapsSearch: MapsSearchResultLike | null = null\n\n if (input.location) {\n mapsSearch = await ctx.client.post<MapsSearchResultLike>('/maps/search', {\n query: input.query,\n location: input.location,\n maxResults: input.maxResultsPerCity,\n proxyMode: input.proxyMode,\n }, 240_000)\n rows = businessRowsFromMaps(input.location, input.query, mapsSearch.results)\n await ctx.artifacts.writeJson('Maps search raw JSON', 'raw/maps-search.json', mapsSearch)\n } else {\n directory = await ctx.client.post<DirectoryWorkflowApiResult>('/directory/run', {\n query: input.query,\n state: input.state,\n minPopulation: input.minPopulation,\n maxCities: input.maxCities,\n maxResultsPerCity: input.maxResultsPerCity,\n concurrency: input.concurrency,\n proxyMode: input.proxyMode,\n saveCsv: true,\n }, 900_000)\n rows = directoryRows(directory)\n await ctx.artifacts.writeJson('Directory raw JSON', 'raw/directory-workflow.json', directory)\n await ctx.artifacts.writeCsv('Directory CSV', 'exports/directory.csv', DIRECTORY_CSV_HEADERS, rows)\n warnings.push(...directory.warnings)\n }\n\n const compareRows = comparisonRows(rows)\n const selected = compareRows.slice(0, input.hydrateTop * Math.max(1, input.location ? 1 : input.maxCities))\n const hydrated = await mapLimit(selected, 3, async (row, index) => {\n try {\n const detail = await ctx.client.post<MapsPlaceIntelResult>('/maps/place', {\n businessName: row.business_name,\n location: row.source_location,\n includeReviews: input.maxReviews > 0,\n maxReviews: Math.max(1, input.maxReviews),\n }, 180_000)\n await ctx.artifacts.writeJson(`${row.business_name} profile`, `raw/maps-place-intel/${index + 1}-${String(row.business_name).toLowerCase().replace(/[^a-z0-9]+/g, '-')}.json`, detail)\n return { row, detail, error: '' }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n warnings.push(`Profile hydration failed for ${row.business_name}: ${message}`)\n return { row, detail: null, error: message }\n }\n })\n\n const profileRows = hydrated.map(({ row, detail, error }) => ({\n source_location: row.source_location,\n result_position: row.result_position,\n business_name: row.business_name,\n category: detail?.category ?? row.category,\n review_stars: detail?.rating ?? row.review_stars,\n review_count: detail?.reviewCount ?? row.review_count,\n website_url: detail?.website ?? row.website_url,\n review_topics: (detail?.reviewTopics ?? []).map(t => `${t.label} (${t.count})`).join('; '),\n about_attributes: (detail?.aboutAttributes ?? []).map(a => `${a.section}: ${a.attribute}`).join('; '),\n reviews_status: detail?.reviewsStatus ?? '',\n error,\n }))\n const markets = marketRows(rows)\n await ctx.artifacts.writeCsv('Maps results CSV', 'maps-results.csv', ['source_query', 'source_location', 'city', 'state', 'population', 'result_position', 'business_name', 'review_stars', 'review_count', 'category', 'address', 'phone', 'website_url', 'place_url', 'cid', 'cid_decimal', 'result_status', 'error'], rows)\n await ctx.artifacts.writeCsv('Comparison CSV', 'map-comparison.csv', ['source_location', 'result_position', 'business_name', 'category', 'review_stars', 'review_count', 'review_gap_to_top3_average', 'website_url', 'place_url', 'comparison_note'], compareRows)\n await ctx.artifacts.writeCsv('Profile insights CSV', 'profile-insights.csv', ['source_location', 'result_position', 'business_name', 'category', 'review_stars', 'review_count', 'website_url', 'review_topics', 'about_attributes', 'reviews_status', 'error'], profileRows)\n await ctx.artifacts.writeJson('Maps comparison evidence', 'evidence.json', { input, directory, mapsSearch, rows, compareRows, profileRows, markets, warnings })\n await ctx.artifacts.writeText('Brief', 'brief.md', [\n `# Maps Comparison: ${input.query}`,\n '',\n `Markets: ${markets.map(row => row.source_location).join(', ')}`,\n '',\n '## How to Use',\n '- Compare rank position against review count and category patterns.',\n '- Treat review gaps and missing websites as opportunity signals, not guarantees.',\n '- Use profile topics and attributes as evidence for local content and GBP improvements.',\n ].join('\\n'))\n\n const summary = `${compareRows.length} Maps competitors compared across ${markets.length} market(s); ${profileRows.filter(row => !row.error).length} profiles hydrated.`\n const reportPath = await ctx.artifacts.writeHtml('HTML report', 'report.html', renderWorkflowReport({\n title: 'Maps Comparison',\n subtitle: `${input.query}${input.location ? ` · ${input.location}` : input.state ? ` · ${input.state}` : ''}`,\n summary,\n warnings,\n tables: [\n { title: 'Market Benchmarks', columns: ['source_location', 'result_count', 'median_review_count', 'median_rating', 'top_three_average_review_count', 'top_categories', 'websites_present'], rows: markets },\n { title: 'Competitor Comparison', columns: ['source_location', 'result_position', 'business_name', 'category', 'review_stars', 'review_count', 'review_gap_to_top3_average', 'comparison_note'], rows: compareRows.slice(0, 120) },\n { title: 'Profile Insights', columns: ['source_location', 'business_name', 'review_topics', 'about_attributes', 'error'], rows: profileRows },\n ],\n }))\n const status = warnings.length ? 'partial' : 'succeeded'\n const counts = { markets: markets.length, competitors: compareRows.length, hydratedProfiles: profileRows.filter(row => !row.error).length }\n await ctx.artifacts.writeManifest(status, counts, warnings, [])\n return { title: 'Maps Comparison', summary, status, counts, warnings, errors: [], reportPath }\n },\n}\n\nexport const serpComparisonWorkflowDefinition: WorkflowDefinition<SerpComparisonInput> = {\n id: 'serp-comparison',\n title: 'SERP Comparison',\n description: 'Compare ranking pages, SERP features, PAA evidence, AI Overview citations, and page-level content gaps.',\n inputSchema: SerpComparisonInputSchema,\n async run(input: SerpComparisonInput, ctx: WorkflowRunContext): Promise<WorkflowRunSummary> {\n await ctx.artifacts.writeManifest('running', {}, [], [])\n const warnings: string[] = []\n const targetDomain = normalizeDomain(input.domain ?? input.url ?? null)\n const serp = await ctx.client.post<HarvestLike>('/harvest/sync', {\n query: input.keyword,\n location: input.location,\n serpOnly: true,\n maxQuestions: 1,\n format: 'json',\n }, 180_000)\n await ctx.artifacts.writeJson('SERP raw JSON', 'raw/serp.json', serp)\n\n let paa: HarvestLike | null = null\n if (input.includePaa) {\n try {\n paa = await ctx.client.post<HarvestLike>('/harvest/sync', {\n query: input.keyword,\n location: input.location,\n maxQuestions: input.maxQuestions,\n format: 'json',\n }, 280_000)\n await ctx.artifacts.writeJson('PAA raw JSON', 'raw/paa.json', paa)\n } catch (err) {\n warnings.push(`PAA evidence unavailable: ${err instanceof Error ? err.message : String(err)}`)\n }\n }\n\n const organic = organicRows(serp, targetDomain).slice(0, input.maxResults)\n const organicSources = (serp.organicResults ?? []).slice(0, input.maxResults)\n const targetSource = input.url\n ? { position: 0, title: 'Target page', url: input.url, domain: domainFromUrl(input.url) }\n : organicSources.find(result => targetDomain && (normalizeDomain(result.domain ?? '') ?? domainFromUrl(result.url)) === targetDomain)\n const competitorSources = organicSources\n .filter(result => result.url && result.url !== targetSource?.url)\n .filter(result => !targetDomain || (normalizeDomain(result.domain ?? '') ?? domainFromUrl(result.url)) !== targetDomain)\n .slice(0, input.extractTop)\n\n const targetPages = targetSource ? await extractPages(ctx, [targetSource], warnings, 'Target') : []\n const competitorPages = input.extractTop > 0 ? await extractPages(ctx, competitorSources, warnings, 'Competitor') : []\n const targetPage = targetPages[0]?.page ?? null\n const pageRows = [\n ...targetPages.map(({ source, page }) => pageSummaryRow(page, { url: source.url ?? '', domain: normalizeDomain(source.domain ?? '') ?? domainFromUrl(source.url), position: source.position, title: source.title })),\n ...competitorPages.map(({ source, page }) => pageSummaryRow(page, { url: source.url ?? '', domain: normalizeDomain(source.domain ?? '') ?? domainFromUrl(source.url), position: source.position, title: source.title })),\n ]\n const gaps = pageGapRows(targetPage, competitorPages)\n const questions = questionRows(paa)\n const aiRows = (serp.aiOverview?.citations ?? []).map((citation, index) => ({\n citation_position: index + 1,\n citation_text: citation.text ?? '',\n url: citation.href ?? '',\n domain: domainFromUrl(citation.href ?? ''),\n is_target: targetDomain ? domainFromUrl(citation.href ?? '') === targetDomain : false,\n }))\n await ctx.artifacts.writeCsv('Organic results CSV', 'organic-results.csv', ['position', 'title', 'url', 'domain', 'snippet', 'is_target'], organic)\n await ctx.artifacts.writeCsv('Page comparison CSV', 'page-comparison.csv', ['position', 'domain', 'url', 'serp_title', 'page_title', 'h1', 'meta_description', 'word_count', 'heading_count', 'schema_types'], pageRows)\n await ctx.artifacts.writeCsv('Content gaps CSV', 'content-gaps.csv', ['source_position', 'source_domain', 'source_url', 'heading_level', 'competitor_heading', 'target_coverage', 'terms'], gaps)\n await ctx.artifacts.writeCsv('PAA questions CSV', 'paa-questions.csv', ['position', 'intent', 'question', 'answer_excerpt', 'source_title', 'source_domain', 'source_url'], questions)\n await ctx.artifacts.writeCsv('AI Overview citations CSV', 'ai-overview-citations.csv', ['citation_position', 'citation_text', 'url', 'domain', 'is_target'], aiRows)\n await ctx.artifacts.writeJson('SERP comparison evidence', 'evidence.json', { input, serp, paa, organic, pageRows, gaps, questions, aiRows, warnings })\n await ctx.artifacts.writeText('Writer brief', 'brief.md', [\n `# SERP Comparison Brief: ${input.keyword}`,\n '',\n `Target: ${targetDomain ?? input.url ?? 'not specified'}`,\n `Location: ${input.location ?? 'not specified'}`,\n '',\n '## Recommended Actions',\n '- Use `content-gaps.csv` to decide which missing sections deserve coverage.',\n '- Use `paa-questions.csv` for FAQ and answer-block candidates.',\n '- Use `ai-overview-citations.csv` to see whether the target is cited in AI Overview evidence.',\n '- Treat extracted page headings as evidence, not a complete semantic analysis.',\n ].join('\\n'))\n const summary = `${organic.length} organic results, ${pageRows.length} extracted pages, ${gaps.length} heading gaps, ${questions.length} PAA questions.`\n const reportPath = await ctx.artifacts.writeHtml('HTML report', 'report.html', renderWorkflowReport({\n title: 'SERP Comparison',\n subtitle: `${input.keyword}${input.location ? ` · ${input.location}` : ''}`,\n summary,\n warnings,\n tables: [\n { title: 'Organic Results', columns: ['position', 'title', 'domain', 'is_target'], rows: organic },\n { title: 'Page Comparison', columns: ['position', 'domain', 'h1', 'word_count', 'heading_count', 'schema_types'], rows: pageRows },\n { title: 'Content Gaps', columns: ['source_position', 'source_domain', 'competitor_heading', 'target_coverage', 'terms'], rows: gaps.slice(0, 80) },\n { title: 'PAA Questions', columns: ['position', 'intent', 'question', 'source_domain'], rows: questions.slice(0, 80) },\n ],\n }))\n const status = warnings.length ? 'partial' : 'succeeded'\n const counts = { organic: organic.length, pages: pageRows.length, gaps: gaps.length, questions: questions.length, aiCitations: aiRows.length }\n await ctx.artifacts.writeManifest(status, counts, warnings, [])\n return { title: 'SERP Comparison', summary, status, counts, warnings, errors: [], reportPath }\n },\n}\n\nexport const paaExpansionBriefWorkflowDefinition: WorkflowDefinition<PaaExpansionBriefInput> = {\n id: 'paa-expansion-brief',\n title: 'PAA Expansion Brief',\n description: 'Expand People Also Ask questions into an evidence-backed writer brief, section map, and source table.',\n inputSchema: PaaExpansionBriefInputSchema,\n async run(input: PaaExpansionBriefInput, ctx: WorkflowRunContext): Promise<WorkflowRunSummary> {\n await ctx.artifacts.writeManifest('running', {}, [], [])\n const warnings: string[] = []\n const paa = await ctx.client.post<HarvestLike>('/harvest/sync', {\n query: input.keyword,\n location: input.location,\n maxQuestions: input.maxQuestions,\n depth: input.depth,\n format: 'json',\n }, 300_000)\n await ctx.artifacts.writeJson('PAA raw JSON', 'raw/paa.json', paa)\n const questions = questionRows(paa)\n const sourceRows = sourceDomainRows(questions)\n const byIntent = new Map<string, Array<Record<string, unknown>>>()\n for (const row of questions) {\n const list = byIntent.get(String(row.intent)) ?? []\n list.push(row)\n byIntent.set(String(row.intent), list)\n }\n const sectionRows = [...byIntent.entries()].map(([intent, rows]) => ({\n recommended_section: intent,\n question_count: rows.length,\n sample_questions: rows.slice(0, 5).map(row => row.question).join(' | '),\n source_domains: [...new Set(rows.map(row => row.source_domain).filter(Boolean))].slice(0, 5).join('; '),\n terms: textTerms(rows.map(row => `${row.question} ${row.answer_excerpt}`).join(' '), 10),\n })).sort((a, b) => Number(b.question_count) - Number(a.question_count))\n\n await ctx.artifacts.writeCsv('PAA questions CSV', 'paa-questions.csv', ['position', 'intent', 'question', 'answer_excerpt', 'source_title', 'source_domain', 'source_url'], questions)\n await ctx.artifacts.writeCsv('Source domains CSV', 'source-domains.csv', ['domain', 'question_mentions', 'source_url_count', 'top_intents'], sourceRows)\n await ctx.artifacts.writeCsv('Section map CSV', 'section-map.csv', ['recommended_section', 'question_count', 'sample_questions', 'source_domains', 'terms'], sectionRows)\n await ctx.artifacts.writeJson('PAA brief evidence', 'evidence.json', { input, paa, questions, sourceRows, sectionRows })\n await ctx.artifacts.writeText('Writer brief', 'writer-brief.md', [\n `# PAA Expansion Brief: ${input.keyword}`,\n '',\n `Location: ${input.location ?? 'not specified'}`,\n '',\n '## Suggested Page Structure',\n ...sectionRows.map(row => `- ${row.recommended_section}: answer ${row.question_count} related question(s). Sample: ${row.sample_questions}`),\n '',\n '## Writing Rules',\n '- Answer the highest-frequency question in the first 60 words of each section.',\n '- Use exact customer question language from `paa-questions.csv` for H2/H3 candidates.',\n '- Use `source-domains.csv` to identify which source types Google is already rewarding.',\n '- Do not invent citations; cite only rows that have a source URL.',\n ].join('\\n'))\n const summary = `${questions.length} PAA questions grouped into ${sectionRows.length} writing sections.`\n const reportPath = await ctx.artifacts.writeHtml('HTML report', 'report.html', renderWorkflowReport({\n title: 'PAA Expansion Brief',\n subtitle: `${input.keyword}${input.location ? ` · ${input.location}` : ''}`,\n summary,\n warnings,\n tables: [\n { title: 'Section Map', columns: ['recommended_section', 'question_count', 'sample_questions', 'source_domains', 'terms'], rows: sectionRows },\n { title: 'Questions', columns: ['position', 'intent', 'question', 'source_domain'], rows: questions.slice(0, 120) },\n { title: 'Source Domains', columns: ['domain', 'question_mentions', 'source_url_count', 'top_intents'], rows: sourceRows },\n ],\n }))\n const counts = { questions: questions.length, sections: sectionRows.length, sourceDomains: sourceRows.length }\n await ctx.artifacts.writeManifest('succeeded', counts, warnings, [])\n return { title: 'PAA Expansion Brief', summary, status: 'succeeded', counts, warnings, errors: [], reportPath }\n },\n}\n\nexport const aiOverviewLanguageWorkflowDefinition: WorkflowDefinition<AiOverviewLanguageInput> = {\n id: 'ai-overview-language',\n title: 'AI Overview Language Brief',\n description: 'Turn AI Overview, citation, PAA, and ranking-page evidence into answer-block and citation-hook guidance.',\n inputSchema: AiOverviewLanguageInputSchema,\n async run(input: AiOverviewLanguageInput, ctx: WorkflowRunContext): Promise<WorkflowRunSummary> {\n await ctx.artifacts.writeManifest('running', {}, [], [])\n const warnings: string[] = []\n const targetDomain = normalizeDomain(input.domain ?? input.url ?? null)\n const serp = await ctx.client.post<HarvestLike>('/harvest/sync', {\n query: input.keyword,\n location: input.location,\n serpOnly: true,\n maxQuestions: 1,\n format: 'json',\n }, 180_000)\n await ctx.artifacts.writeJson('SERP raw JSON', 'raw/serp.json', serp)\n let paa: HarvestLike | null = null\n try {\n paa = await ctx.client.post<HarvestLike>('/harvest/sync', {\n query: input.keyword,\n location: input.location,\n maxQuestions: input.maxQuestions,\n format: 'json',\n }, 280_000)\n await ctx.artifacts.writeJson('PAA raw JSON', 'raw/paa.json', paa)\n } catch (err) {\n warnings.push(`PAA evidence unavailable: ${err instanceof Error ? err.message : String(err)}`)\n }\n\n const citations = (serp.aiOverview?.citations ?? []).map((citation, index) => {\n const domain = domainFromUrl(citation.href ?? '')\n return {\n citation_position: index + 1,\n citation_text: citation.text ?? '',\n url: citation.href ?? '',\n domain,\n is_target: targetDomain ? domain === targetDomain : false,\n }\n })\n const aioSentences = splitSentences(serp.aiOverview?.text)\n const claimRows = aioSentences.map((sentence, index) => ({\n position: index + 1,\n claim_type: classifySentence(sentence),\n sentence,\n reusable_pattern: sentence.length > 140 ? `${sentence.slice(0, 140)}...` : sentence,\n }))\n const questions = questionRows(paa)\n const citationSources = (serp.aiOverview?.citations ?? [])\n .filter(citation => citation.href)\n .map((citation, index) => ({ position: index + 1, title: citation.text, url: citation.href, domain: domainFromUrl(citation.href) }))\n .slice(0, input.extractTop)\n const extractedCitations = input.extractTop > 0 ? await extractPages(ctx, citationSources, warnings, 'Citation') : []\n const extractedRows = extractedCitations.map(({ source, page }) => pageSummaryRow(page, { url: source.url ?? '', domain: normalizeDomain(source.domain ?? '') ?? domainFromUrl(source.url), position: source.position, title: source.title }))\n const languageRows = [\n {\n block: 'direct_answer',\n guidance: 'Open with a 40-70 word answer that directly resolves the query before adding context.',\n evidence_basis: questions[0]?.question ?? input.keyword,\n },\n {\n block: 'criteria_or_steps',\n guidance: 'List the criteria, steps, or decision factors Google is already compressing into AI Overview language.',\n evidence_basis: claimRows.filter(row => ['criteria', 'process'].includes(String(row.claim_type))).map(row => row.sentence).slice(0, 3).join(' | '),\n },\n {\n block: 'citation_hook',\n guidance: 'Add source-worthy details competitors can cite: definitions, numbers, examples, process details, and named entity relationships.',\n evidence_basis: citations.map(row => `${row.domain}: ${row.citation_text}`).slice(0, 5).join(' | '),\n },\n {\n block: 'faq_followups',\n guidance: 'Use PAA phrasing for follow-up sections so the page answers adjacent questions in Google language.',\n evidence_basis: questions.slice(0, 5).map(row => row.question).join(' | '),\n },\n ]\n await ctx.artifacts.writeCsv('AI Overview citations CSV', 'ai-overview-citations.csv', ['citation_position', 'citation_text', 'url', 'domain', 'is_target'], citations)\n await ctx.artifacts.writeCsv('AI Overview claim patterns CSV', 'claim-patterns.csv', ['position', 'claim_type', 'sentence', 'reusable_pattern'], claimRows)\n await ctx.artifacts.writeCsv('Language guidance CSV', 'language-guidance.csv', ['block', 'guidance', 'evidence_basis'], languageRows)\n await ctx.artifacts.writeCsv('PAA questions CSV', 'paa-questions.csv', ['position', 'intent', 'question', 'answer_excerpt', 'source_title', 'source_domain', 'source_url'], questions)\n await ctx.artifacts.writeCsv('Extracted citation pages CSV', 'citation-pages.csv', ['position', 'domain', 'url', 'serp_title', 'page_title', 'h1', 'meta_description', 'word_count', 'heading_count', 'schema_types'], extractedRows)\n await ctx.artifacts.writeJson('AI Overview language evidence', 'evidence.json', { input, serp, paa, citations, claimRows, languageRows, extractedRows, warnings })\n await ctx.artifacts.writeText('Answer block template', 'answer-block-template.md', [\n `# AI Overview Language Brief: ${input.keyword}`,\n '',\n `AI Overview detected: ${serp.aiOverview?.detected ? 'yes' : 'no'}`,\n `Target cited: ${targetDomain ? citations.some(row => row.is_target) ? 'yes' : 'no' : 'target not specified'}`,\n '',\n '## Direct Answer Block',\n 'Write one compact answer block that starts with the answer, not background. Keep it clear enough that Google could lift it as a standalone summary.',\n '',\n '## Suggested Follow-Up Blocks',\n ...languageRows.map(row => `- ${row.block}: ${row.guidance}`),\n '',\n '## Evidence to Mirror',\n ...claimRows.slice(0, 8).map(row => `- ${row.claim_type}: ${row.sentence}`),\n '',\n '## Citation Hooks',\n ...citations.slice(0, 8).map(row => `- ${row.domain}: ${row.citation_text}`),\n ].join('\\n'))\n const summary = `${citations.length} AI Overview citations, ${claimRows.length} claim patterns, ${questions.length} PAA questions, ${extractedRows.length} citation pages extracted.`\n const reportPath = await ctx.artifacts.writeHtml('HTML report', 'report.html', renderWorkflowReport({\n title: 'AI Overview Language Brief',\n subtitle: `${input.keyword}${input.location ? ` · ${input.location}` : ''}`,\n summary,\n warnings,\n tables: [\n { title: 'Language Guidance', columns: ['block', 'guidance', 'evidence_basis'], rows: languageRows },\n { title: 'AI Overview Citations', columns: ['citation_position', 'citation_text', 'domain', 'is_target'], rows: citations },\n { title: 'Claim Patterns', columns: ['position', 'claim_type', 'sentence'], rows: claimRows },\n { title: 'PAA Follow-Ups', columns: ['position', 'intent', 'question', 'source_domain'], rows: questions.slice(0, 60) },\n ],\n }))\n const status = warnings.length || !serp.aiOverview?.detected ? 'partial' : 'succeeded'\n const counts = { citations: citations.length, claimPatterns: claimRows.length, questions: questions.length, extractedCitationPages: extractedRows.length }\n await ctx.artifacts.writeManifest(status, counts, warnings, [])\n return { title: 'AI Overview Language Brief', summary, status, counts, warnings, errors: [], reportPath }\n },\n}\n","export interface OrganicResult {\n position?: number\n title?: string\n url?: string\n domain?: string\n snippet?: string | null\n}\n\nexport interface PaaFlatRow {\n question?: string\n answer?: string | null\n source_title?: string | null\n source_site?: string | null\n source_cite?: string | null\n}\n\nexport interface HarvestLike {\n organicResults?: OrganicResult[]\n localPack?: Array<{ position?: number; name?: string; rating?: string | null; reviewCount?: string | null; websiteUrl?: string | null }>\n flat?: PaaFlatRow[]\n aiOverview?: { detected?: boolean; text?: string | null; citations?: Array<{ text?: string; href?: string }> }\n forumResults?: Array<{ title?: string; source?: string; url?: string }>\n videoResults?: Array<{ title?: string; channel?: string; platform?: string; url?: string }>\n}\n\nexport interface ExtractUrlResult {\n url?: string\n canonicalUrl?: string | null\n title?: string | null\n metaDescription?: string | null\n h1?: string | null\n headings?: Array<{ level: number; text: string }>\n wordCount?: number\n schemaTypes?: string[]\n bodyMarkdown?: string\n}\n\nexport interface MapsSearchBusinessLike {\n position: number\n name: string\n rating?: string | null\n reviewCount?: string | null\n category?: string | null\n address?: string | null\n phone?: string | null\n websiteUrl?: string | null\n placeUrl?: string\n cid?: string | null\n cidDecimal?: string | null\n hoursStatus?: string | null\n}\n\nexport interface MapsSearchResultLike {\n query: string\n location?: string | null\n searchQuery?: string\n resultCount: number\n results: MapsSearchBusinessLike[]\n}\n\nconst STOP_WORDS = new Set([\n 'about', 'after', 'also', 'because', 'been', 'best', 'both', 'from', 'have', 'into',\n 'more', 'most', 'near', 'only', 'over', 'than', 'that', 'their', 'them', 'then',\n 'there', 'these', 'they', 'this', 'what', 'when', 'where', 'which', 'while', 'with',\n 'your', 'will', 'would', 'should', 'could', 'does', 'were', 'cost', 'costs',\n])\n\nexport function normalizeDomain(value?: string | null): string | null {\n if (!value) return null\n try {\n const url = new URL(value.includes('://') ? value : `https://${value}`)\n return url.hostname.replace(/^www\\./, '').toLowerCase()\n } catch {\n return value.replace(/^https?:\\/\\//, '').replace(/^www\\./, '').split('/')[0]?.toLowerCase() || null\n }\n}\n\nexport function domainFromUrl(url?: string | null): string {\n return normalizeDomain(url) ?? ''\n}\n\nexport function numberFrom(value: unknown): number | null {\n if (value === null || value === undefined || value === '') return null\n const parsed = Number(String(value).replace(/[^\\d.]/g, ''))\n return Number.isFinite(parsed) ? parsed : null\n}\n\nexport function median(values: Array<number | null>): number | null {\n const nums = values.filter((v): v is number => v !== null).sort((a, b) => a - b)\n if (!nums.length) return null\n return nums[Math.floor(nums.length / 2)] ?? null\n}\n\nexport function textTerms(text: string, limit = 12): string {\n const counts = new Map<string, number>()\n for (const token of text.toLowerCase().replace(/[^a-z0-9\\s]/g, ' ').split(/\\s+/)) {\n if (token.length < 4 || STOP_WORDS.has(token)) continue\n counts.set(token, (counts.get(token) ?? 0) + 1)\n }\n return [...counts.entries()]\n .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))\n .slice(0, limit)\n .map(([term, count]) => `${term} (${count})`)\n .join('; ')\n}\n\nexport function classifyQuestion(question: string): string {\n const q = question.toLowerCase()\n if (/\\b(cost|price|pricing|charge|expensive|cheap)\\b/.test(q)) return 'cost'\n if (/\\b(best|top|recommended|reviews?|compare|versus|vs)\\b/.test(q)) return 'comparison'\n if (/\\b(how|steps?|process|way to)\\b/.test(q)) return 'process'\n if (/\\b(why|worth|important|benefit)\\b/.test(q)) return 'why'\n if (/\\b(near me|city|local|nearby)\\b/.test(q)) return 'local'\n if (/\\b(can|does|do|is|are|should|will)\\b/.test(q)) return 'decision'\n return 'definition'\n}\n\nexport function questionRows(paa: HarvestLike | null): Array<Record<string, unknown>> {\n return (paa?.flat ?? [])\n .filter(row => row.question)\n .map((row, index) => {\n const url = row.source_cite ?? ''\n const domain = normalizeDomain(row.source_site ?? '') ?? domainFromUrl(url)\n return {\n position: index + 1,\n intent: classifyQuestion(row.question ?? ''),\n question: row.question ?? '',\n answer_excerpt: (row.answer ?? '').slice(0, 320),\n source_title: row.source_title ?? '',\n source_domain: domain,\n source_url: url,\n }\n })\n}\n\nexport function sourceDomainRows(rows: Array<Record<string, unknown>>): Array<Record<string, unknown>> {\n const byDomain = new Map<string, { questions: number; urls: Set<string>; intents: Map<string, number> }>()\n for (const row of rows) {\n const domain = String(row.source_domain ?? row.domain ?? '')\n if (!domain) continue\n const entry = byDomain.get(domain) ?? { questions: 0, urls: new Set<string>(), intents: new Map<string, number>() }\n entry.questions += row.question ? 1 : 0\n if (row.source_url || row.url) entry.urls.add(String(row.source_url ?? row.url))\n if (row.intent) entry.intents.set(String(row.intent), (entry.intents.get(String(row.intent)) ?? 0) + 1)\n byDomain.set(domain, entry)\n }\n return [...byDomain.entries()]\n .map(([domain, entry]) => ({\n domain,\n question_mentions: entry.questions,\n source_url_count: entry.urls.size,\n top_intents: [...entry.intents.entries()].sort((a, b) => b[1] - a[1]).map(([intent, count]) => `${intent} (${count})`).join('; '),\n }))\n .sort((a, b) => Number(b.question_mentions) - Number(a.question_mentions) || String(a.domain).localeCompare(String(b.domain)))\n}\n\nexport function splitSentences(text?: string | null): string[] {\n return (text ?? '')\n .replace(/\\s+/g, ' ')\n .split(/(?<=[.!?])\\s+/)\n .map(sentence => sentence.trim())\n .filter(sentence => sentence.length > 20)\n .slice(0, 20)\n}\n\nexport function classifySentence(sentence: string): string {\n const s = sentence.toLowerCase()\n if (/\\bis\\b|\\bare\\b|\\bmeans\\b|\\brefers to\\b/.test(s)) return 'definition'\n if (/\\binclude\\b|\\bconsider\\b|\\bfactors?\\b|\\bcriteria\\b/.test(s)) return 'criteria'\n if (/\\bfirst\\b|\\bthen\\b|\\bsteps?\\b|\\bprocess\\b/.test(s)) return 'process'\n if (/\\bvs\\b|\\bthan\\b|\\bcompare\\b|\\bdifference\\b/.test(s)) return 'comparison'\n if (/\\bcost\\b|\\bprice\\b|\\baverage\\b|\\brange\\b/.test(s)) return 'cost'\n return 'claim'\n}\n\nexport function headingRows(page: ExtractUrlResult, source: { url: string; domain: string; position?: number | string }): Array<Record<string, unknown>> {\n return (page.headings ?? [])\n .filter(heading => heading.text)\n .map(heading => ({\n source_url: source.url,\n source_domain: source.domain,\n source_position: source.position ?? '',\n heading_level: heading.level,\n heading_text: heading.text,\n heading_terms: textTerms(heading.text, 6),\n }))\n}\n\nexport function pageSummaryRow(page: ExtractUrlResult, source: { url: string; domain: string; position?: number | string; title?: string }): Record<string, unknown> {\n return {\n position: source.position ?? '',\n domain: source.domain,\n url: source.url,\n serp_title: source.title ?? '',\n page_title: page.title ?? '',\n h1: page.h1 ?? '',\n meta_description: page.metaDescription ?? '',\n word_count: page.wordCount ?? '',\n heading_count: page.headings?.length ?? 0,\n schema_types: (page.schemaTypes ?? []).join('; '),\n }\n}\n\nexport async function mapLimit<T, R>(items: T[], limit: number, fn: (item: T, index: number) => Promise<R>): Promise<R[]> {\n const out: R[] = new Array(items.length)\n let next = 0\n async function worker(): Promise<void> {\n while (next < items.length) {\n const index = next\n next += 1\n out[index] = await fn(items[index], index)\n }\n }\n await Promise.all(Array.from({ length: Math.min(Math.max(1, limit), items.length) }, () => worker()))\n return out\n}\n\n","#!/usr/bin/env node\nimport { runHumanCli } from '../src/cli/human-cli.js'\n\nrunHumanCli().catch((err) => {\n console.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n})\n\n"],"mappings":"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","names":["import_node_child_process","import_promises","import_node_path","import_promises","import_node_os","import_node_path","status","import_promises","import_zod","status","import_zod","import_zod","status","import_zod","status","import_zod","mapLimit","competitorRows","status","import_zod","normalizeDomain","domainFromUrl","numberFrom","median","mapLimit","numberFrom","median","normalizeDomain","domainFromUrl","mapLimit","status","sourceRows"]}