mcp-scraper 0.3.46 → 0.4.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.
Files changed (50) hide show
  1. package/dist/bin/api-server.cjs +2800 -346
  2. package/dist/bin/api-server.cjs.map +1 -1
  3. package/dist/bin/api-server.js +2 -2
  4. package/dist/bin/mcp-scraper-cli.cjs +1 -1
  5. package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
  6. package/dist/bin/mcp-scraper-cli.js +3 -3
  7. package/dist/bin/mcp-scraper-install.cjs +1 -1
  8. package/dist/bin/mcp-scraper-install.cjs.map +1 -1
  9. package/dist/bin/mcp-scraper-install.js +1 -1
  10. package/dist/bin/mcp-stdio-server.cjs +2100 -23
  11. package/dist/bin/mcp-stdio-server.cjs.map +1 -1
  12. package/dist/bin/mcp-stdio-server.js +9 -4
  13. package/dist/bin/mcp-stdio-server.js.map +1 -1
  14. package/dist/bin/paa-harvest.js +3 -2
  15. package/dist/bin/paa-harvest.js.map +1 -1
  16. package/dist/{chunk-SS5YBZVI.js → chunk-3NIPPJGP.js} +2184 -514
  17. package/dist/chunk-3NIPPJGP.js.map +1 -0
  18. package/dist/chunk-3UH3BEIZ.js +158 -0
  19. package/dist/chunk-3UH3BEIZ.js.map +1 -0
  20. package/dist/{chunk-BRVX6RDN.js → chunk-6TDUY7CA.js} +5 -159
  21. package/dist/chunk-6TDUY7CA.js.map +1 -0
  22. package/dist/chunk-GWRIO6JT.js +419 -0
  23. package/dist/chunk-GWRIO6JT.js.map +1 -0
  24. package/dist/{chunk-RXNHY3TF.js → chunk-HBC4C75S.js} +11 -9
  25. package/dist/{chunk-RXNHY3TF.js.map → chunk-HBC4C75S.js.map} +1 -1
  26. package/dist/chunk-HPV4VOQX.js +27 -0
  27. package/dist/chunk-HPV4VOQX.js.map +1 -0
  28. package/dist/chunk-IXDYL7TE.js +7 -0
  29. package/dist/chunk-IXDYL7TE.js.map +1 -0
  30. package/dist/chunk-JOEZJL4I.js +130 -0
  31. package/dist/chunk-JOEZJL4I.js.map +1 -0
  32. package/dist/{chunk-3PRO376E.js → chunk-M2S27J6Z.js} +1 -25
  33. package/dist/chunk-M2S27J6Z.js.map +1 -0
  34. package/dist/extract-bundle-UKE273TV.js +276 -0
  35. package/dist/extract-bundle-UKE273TV.js.map +1 -0
  36. package/dist/index.js +3 -2
  37. package/dist/index.js.map +1 -1
  38. package/dist/{server-MGE3GYJW.js → server-Z4WKTE6F.js} +169 -195
  39. package/dist/server-Z4WKTE6F.js.map +1 -0
  40. package/dist/site-extract-repository-2MQBAOX5.js +30 -0
  41. package/dist/site-extract-repository-2MQBAOX5.js.map +1 -0
  42. package/dist/{worker-4CVMSUZR.js → worker-RVZXIALX.js} +8 -5
  43. package/dist/{worker-4CVMSUZR.js.map → worker-RVZXIALX.js.map} +1 -1
  44. package/package.json +2 -1
  45. package/dist/chunk-3PRO376E.js.map +0 -1
  46. package/dist/chunk-BRVX6RDN.js.map +0 -1
  47. package/dist/chunk-SS5YBZVI.js.map +0 -1
  48. package/dist/chunk-WT6OT2T3.js +0 -7
  49. package/dist/chunk-WT6OT2T3.js.map +0 -1
  50. package/dist/server-MGE3GYJW.js.map +0 -1
@@ -1,19 +1,23 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  HttpMcpToolExecutor,
4
+ MemoryMcpToolExecutor,
4
5
  SERVER_INSTRUCTIONS,
5
6
  registerBrowserAgentMcpTools,
7
+ registerMemoryMcpTools,
6
8
  registerPaaExtractorMcpTools,
7
9
  registerSerpIntelligenceCaptureTools
8
- } from "../chunk-SS5YBZVI.js";
10
+ } from "../chunk-3NIPPJGP.js";
11
+ import "../chunk-GWRIO6JT.js";
12
+ import "../chunk-HPV4VOQX.js";
9
13
  import {
10
14
  renderInstallTerminal
11
15
  } from "../chunk-T3VZD2I4.js";
16
+ import "../chunk-BP27CZ5Q.js";
12
17
  import {
13
18
  PACKAGE_VERSION
14
- } from "../chunk-WT6OT2T3.js";
15
- import "../chunk-3PRO376E.js";
16
- import "../chunk-BP27CZ5Q.js";
19
+ } from "../chunk-IXDYL7TE.js";
20
+ import "../chunk-M2S27J6Z.js";
17
21
 
18
22
  // bin/mcp-stdio-server.ts
19
23
  import { readFileSync } from "fs";
@@ -57,6 +61,7 @@ var httpExecutor = new HttpMcpToolExecutor(baseUrl, apiKey);
57
61
  registerPaaExtractorMcpTools(server, httpExecutor);
58
62
  registerSerpIntelligenceCaptureTools(server, httpExecutor);
59
63
  registerBrowserAgentMcpTools(server, { baseUrl, apiKey, consoleBaseUrl });
64
+ registerMemoryMcpTools(server, new MemoryMcpToolExecutor(baseUrl, apiKey));
60
65
  var transport = new StdioServerTransport();
61
66
  async function main() {
62
67
  await server.connect(transport);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../bin/mcp-stdio-server.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { HttpMcpToolExecutor } from '../src/mcp/http-mcp-tool-executor.js'\nimport { registerBrowserAgentMcpTools } from '../src/mcp/browser-agent-mcp-server.js'\nimport { registerPaaExtractorMcpTools, registerSerpIntelligenceCaptureTools } from '../src/mcp/paa-mcp-server.js'\nimport { SERVER_INSTRUCTIONS } from '../src/mcp/server-instructions.js'\nimport { renderInstallTerminal } from '../src/install-terminal.js'\nimport { PACKAGE_VERSION } from '../src/version.js'\n\nconst forceStdio =\n process.argv.includes('--stdio') ||\n process.env.MCP_SCRAPER_FORCE_STDIO === '1'\nconst interactiveTerminal = Boolean(process.stdin.isTTY && process.stdout.isTTY)\nconst wantsHelp = process.argv.includes('--help') || process.argv.includes('-h')\n\nif (!forceStdio && (interactiveTerminal || wantsHelp)) {\n const noColor =\n process.argv.includes('--no-color') ||\n process.env.NO_COLOR !== undefined ||\n process.env.FORCE_COLOR === '0' ||\n !process.stdout.isTTY\n\n process.stdout.write(renderInstallTerminal({\n version: PACKAGE_VERSION,\n color: !noColor,\n apiKeyConfigured: Boolean(process.env.MCP_SCRAPER_API_KEY?.trim()),\n }))\n process.exit(0)\n}\n\nfunction readApiKeyFile(): string | undefined {\n const explicitPath = process.env.MCP_SCRAPER_KEY_PATH?.trim()\n const paths = [explicitPath, join(homedir(), '.mcp-scraper-key')].filter(Boolean) as string[]\n for (const path of paths) {\n try {\n const value = readFileSync(path, 'utf8').trim()\n if (value) return value\n } catch {\n void 0\n }\n }\n return undefined\n}\n\nconst apiKey = (\n process.env.MCP_SCRAPER_API_KEY ??\n process.env.MCP_SCRAPER_KEY ??\n process.env.MCP_API_KEY ??\n readApiKeyFile()\n)?.trim()\nif (!apiKey) {\n process.stderr.write('MCP_SCRAPER_API_KEY env var or ~/.mcp-scraper-key is required\\n')\n process.exit(1)\n}\n\nconst baseUrl = process.env.MCP_SCRAPER_BASE_URL?.trim() || process.env.MCP_BASE_URL?.trim() || 'https://mcpscraper.dev'\nconst consoleBaseUrl = process.env.BROWSER_AGENT_CONSOLE_URL?.trim() || baseUrl\nconst server = new McpServer({ name: 'mcp-scraper', version: PACKAGE_VERSION }, { instructions: SERVER_INSTRUCTIONS })\n\nconst httpExecutor = new HttpMcpToolExecutor(baseUrl, apiKey)\nregisterPaaExtractorMcpTools(server, httpExecutor)\nregisterSerpIntelligenceCaptureTools(server, httpExecutor)\nregisterBrowserAgentMcpTools(server, { baseUrl, apiKey, consoleBaseUrl })\n\nconst transport = new StdioServerTransport()\n\nasync function main() {\n await server.connect(transport)\n}\n\nmain().catch(err => {\n process.stderr.write(`${err instanceof Error ? err.message : String(err)}\\n`)\n process.exit(1)\n})\n"],"mappings":";;;;;;;;;;;;;;;;;;AACA,SAAS,oBAAoB;AAC7B,SAAS,eAAe;AACxB,SAAS,YAAY;AACrB,SAAS,iBAAiB;AAC1B,SAAS,4BAA4B;AAQrC,IAAM,aACJ,QAAQ,KAAK,SAAS,SAAS,KAC/B,QAAQ,IAAI,4BAA4B;AAC1C,IAAM,sBAAsB,QAAQ,QAAQ,MAAM,SAAS,QAAQ,OAAO,KAAK;AAC/E,IAAM,YAAY,QAAQ,KAAK,SAAS,QAAQ,KAAK,QAAQ,KAAK,SAAS,IAAI;AAE/E,IAAI,CAAC,eAAe,uBAAuB,YAAY;AACrD,QAAM,UACJ,QAAQ,KAAK,SAAS,YAAY,KAClC,QAAQ,IAAI,aAAa,UACzB,QAAQ,IAAI,gBAAgB,OAC5B,CAAC,QAAQ,OAAO;AAElB,UAAQ,OAAO,MAAM,sBAAsB;AAAA,IACzC,SAAS;AAAA,IACT,OAAO,CAAC;AAAA,IACR,kBAAkB,QAAQ,QAAQ,IAAI,qBAAqB,KAAK,CAAC;AAAA,EACnE,CAAC,CAAC;AACF,UAAQ,KAAK,CAAC;AAChB;AAEA,SAAS,iBAAqC;AAC5C,QAAM,eAAe,QAAQ,IAAI,sBAAsB,KAAK;AAC5D,QAAM,QAAQ,CAAC,cAAc,KAAK,QAAQ,GAAG,kBAAkB,CAAC,EAAE,OAAO,OAAO;AAChF,aAAW,QAAQ,OAAO;AACxB,QAAI;AACF,YAAM,QAAQ,aAAa,MAAM,MAAM,EAAE,KAAK;AAC9C,UAAI,MAAO,QAAO;AAAA,IACpB,QAAQ;AAAA,IAER;AAAA,EACF;AACA,SAAO;AACT;AAEA,IAAM,UACJ,QAAQ,IAAI,uBACZ,QAAQ,IAAI,mBACZ,QAAQ,IAAI,eACZ,eAAe,IACd,KAAK;AACR,IAAI,CAAC,QAAQ;AACX,UAAQ,OAAO,MAAM,iEAAiE;AACtF,UAAQ,KAAK,CAAC;AAChB;AAEA,IAAM,UAAU,QAAQ,IAAI,sBAAsB,KAAK,KAAK,QAAQ,IAAI,cAAc,KAAK,KAAK;AAChG,IAAM,iBAAiB,QAAQ,IAAI,2BAA2B,KAAK,KAAK;AACxE,IAAM,SAAS,IAAI,UAAU,EAAE,MAAM,eAAe,SAAS,gBAAgB,GAAG,EAAE,cAAc,oBAAoB,CAAC;AAErH,IAAM,eAAe,IAAI,oBAAoB,SAAS,MAAM;AAC5D,6BAA6B,QAAQ,YAAY;AACjD,qCAAqC,QAAQ,YAAY;AACzD,6BAA6B,QAAQ,EAAE,SAAS,QAAQ,eAAe,CAAC;AAExE,IAAM,YAAY,IAAI,qBAAqB;AAE3C,eAAe,OAAO;AACpB,QAAM,OAAO,QAAQ,SAAS;AAChC;AAEA,KAAK,EAAE,MAAM,SAAO;AAClB,UAAQ,OAAO,MAAM,GAAG,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,CAAI;AAC5E,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":[]}
1
+ {"version":3,"sources":["../../bin/mcp-stdio-server.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { HttpMcpToolExecutor } from '../src/mcp/http-mcp-tool-executor.js'\nimport { registerBrowserAgentMcpTools } from '../src/mcp/browser-agent-mcp-server.js'\nimport { registerPaaExtractorMcpTools, registerSerpIntelligenceCaptureTools } from '../src/mcp/paa-mcp-server.js'\nimport { registerMemoryMcpTools } from '../src/mcp/memory-mcp-server.js'\nimport { MemoryMcpToolExecutor } from '../src/mcp/memory-mcp-tool-executor.js'\nimport { SERVER_INSTRUCTIONS } from '../src/mcp/server-instructions.js'\nimport { renderInstallTerminal } from '../src/install-terminal.js'\nimport { PACKAGE_VERSION } from '../src/version.js'\n\nconst forceStdio =\n process.argv.includes('--stdio') ||\n process.env.MCP_SCRAPER_FORCE_STDIO === '1'\nconst interactiveTerminal = Boolean(process.stdin.isTTY && process.stdout.isTTY)\nconst wantsHelp = process.argv.includes('--help') || process.argv.includes('-h')\n\nif (!forceStdio && (interactiveTerminal || wantsHelp)) {\n const noColor =\n process.argv.includes('--no-color') ||\n process.env.NO_COLOR !== undefined ||\n process.env.FORCE_COLOR === '0' ||\n !process.stdout.isTTY\n\n process.stdout.write(renderInstallTerminal({\n version: PACKAGE_VERSION,\n color: !noColor,\n apiKeyConfigured: Boolean(process.env.MCP_SCRAPER_API_KEY?.trim()),\n }))\n process.exit(0)\n}\n\nfunction readApiKeyFile(): string | undefined {\n const explicitPath = process.env.MCP_SCRAPER_KEY_PATH?.trim()\n const paths = [explicitPath, join(homedir(), '.mcp-scraper-key')].filter(Boolean) as string[]\n for (const path of paths) {\n try {\n const value = readFileSync(path, 'utf8').trim()\n if (value) return value\n } catch {\n void 0\n }\n }\n return undefined\n}\n\nconst apiKey = (\n process.env.MCP_SCRAPER_API_KEY ??\n process.env.MCP_SCRAPER_KEY ??\n process.env.MCP_API_KEY ??\n readApiKeyFile()\n)?.trim()\nif (!apiKey) {\n process.stderr.write('MCP_SCRAPER_API_KEY env var or ~/.mcp-scraper-key is required\\n')\n process.exit(1)\n}\n\nconst baseUrl = process.env.MCP_SCRAPER_BASE_URL?.trim() || process.env.MCP_BASE_URL?.trim() || 'https://mcpscraper.dev'\nconst consoleBaseUrl = process.env.BROWSER_AGENT_CONSOLE_URL?.trim() || baseUrl\nconst server = new McpServer({ name: 'mcp-scraper', version: PACKAGE_VERSION }, { instructions: SERVER_INSTRUCTIONS })\n\nconst httpExecutor = new HttpMcpToolExecutor(baseUrl, apiKey)\nregisterPaaExtractorMcpTools(server, httpExecutor)\nregisterSerpIntelligenceCaptureTools(server, httpExecutor)\nregisterBrowserAgentMcpTools(server, { baseUrl, apiKey, consoleBaseUrl })\nregisterMemoryMcpTools(server, new MemoryMcpToolExecutor(baseUrl, apiKey))\n\nconst transport = new StdioServerTransport()\n\nasync function main() {\n await server.connect(transport)\n}\n\nmain().catch(err => {\n process.stderr.write(`${err instanceof Error ? err.message : String(err)}\\n`)\n process.exit(1)\n})\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AACA,SAAS,oBAAoB;AAC7B,SAAS,eAAe;AACxB,SAAS,YAAY;AACrB,SAAS,iBAAiB;AAC1B,SAAS,4BAA4B;AAUrC,IAAM,aACJ,QAAQ,KAAK,SAAS,SAAS,KAC/B,QAAQ,IAAI,4BAA4B;AAC1C,IAAM,sBAAsB,QAAQ,QAAQ,MAAM,SAAS,QAAQ,OAAO,KAAK;AAC/E,IAAM,YAAY,QAAQ,KAAK,SAAS,QAAQ,KAAK,QAAQ,KAAK,SAAS,IAAI;AAE/E,IAAI,CAAC,eAAe,uBAAuB,YAAY;AACrD,QAAM,UACJ,QAAQ,KAAK,SAAS,YAAY,KAClC,QAAQ,IAAI,aAAa,UACzB,QAAQ,IAAI,gBAAgB,OAC5B,CAAC,QAAQ,OAAO;AAElB,UAAQ,OAAO,MAAM,sBAAsB;AAAA,IACzC,SAAS;AAAA,IACT,OAAO,CAAC;AAAA,IACR,kBAAkB,QAAQ,QAAQ,IAAI,qBAAqB,KAAK,CAAC;AAAA,EACnE,CAAC,CAAC;AACF,UAAQ,KAAK,CAAC;AAChB;AAEA,SAAS,iBAAqC;AAC5C,QAAM,eAAe,QAAQ,IAAI,sBAAsB,KAAK;AAC5D,QAAM,QAAQ,CAAC,cAAc,KAAK,QAAQ,GAAG,kBAAkB,CAAC,EAAE,OAAO,OAAO;AAChF,aAAW,QAAQ,OAAO;AACxB,QAAI;AACF,YAAM,QAAQ,aAAa,MAAM,MAAM,EAAE,KAAK;AAC9C,UAAI,MAAO,QAAO;AAAA,IACpB,QAAQ;AAAA,IAER;AAAA,EACF;AACA,SAAO;AACT;AAEA,IAAM,UACJ,QAAQ,IAAI,uBACZ,QAAQ,IAAI,mBACZ,QAAQ,IAAI,eACZ,eAAe,IACd,KAAK;AACR,IAAI,CAAC,QAAQ;AACX,UAAQ,OAAO,MAAM,iEAAiE;AACtF,UAAQ,KAAK,CAAC;AAChB;AAEA,IAAM,UAAU,QAAQ,IAAI,sBAAsB,KAAK,KAAK,QAAQ,IAAI,cAAc,KAAK,KAAK;AAChG,IAAM,iBAAiB,QAAQ,IAAI,2BAA2B,KAAK,KAAK;AACxE,IAAM,SAAS,IAAI,UAAU,EAAE,MAAM,eAAe,SAAS,gBAAgB,GAAG,EAAE,cAAc,oBAAoB,CAAC;AAErH,IAAM,eAAe,IAAI,oBAAoB,SAAS,MAAM;AAC5D,6BAA6B,QAAQ,YAAY;AACjD,qCAAqC,QAAQ,YAAY;AACzD,6BAA6B,QAAQ,EAAE,SAAS,QAAQ,eAAe,CAAC;AACxE,uBAAuB,QAAQ,IAAI,sBAAsB,SAAS,MAAM,CAAC;AAEzE,IAAM,YAAY,IAAI,qBAAqB;AAE3C,eAAe,OAAO;AACpB,QAAM,OAAO,QAAQ,SAAS;AAChC;AAEA,KAAK,EAAE,MAAM,SAAO;AAClB,UAAQ,OAAO,MAAM,GAAG,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,CAAI;AAC5E,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":[]}
@@ -1,12 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  harvest
4
- } from "../chunk-RXNHY3TF.js";
4
+ } from "../chunk-HBC4C75S.js";
5
5
  import {
6
6
  browserServiceApiKey
7
- } from "../chunk-3PRO376E.js";
7
+ } from "../chunk-HPV4VOQX.js";
8
8
  import "../chunk-K443GQY5.js";
9
9
  import "../chunk-BP27CZ5Q.js";
10
+ import "../chunk-M2S27J6Z.js";
10
11
  import "../chunk-FUVQR6GK.js";
11
12
 
12
13
  // src/cli.ts
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli.ts","../../bin/paa-harvest.ts"],"sourcesContent":["import { Command } from 'commander'\nimport { browserServiceApiKey } from './lib/browser-service-env.js'\nimport { harvest } from './harvest.js'\n\nconst program = new Command()\n\nprogram\n .name('paa-harvest')\n .description('Recursively extract Google People Also Ask questions')\n .requiredOption('-q, --query <query>', 'Seed query')\n .option('-l, --location <location>', 'Location name (e.g. \"austin\" or \"Austin,Texas,United States\")')\n .option('--gl <gl>', 'Google country code', 'us')\n .option('--hl <hl>', 'Google language code', 'en')\n .option('-d, --depth <depth>', 'BFS depth (1-30)', '3')\n .option('-m, --max-questions <n>', 'Max questions to harvest', '100')\n .option('-o, --output <dir>', 'Output directory', './paa-output')\n .option('-f, --format <format>', 'Output format: json, csv, or both', 'both')\n .option('--headless', 'Run browser in headless mode', false)\n .option('--profile <dir>', 'Persistent browser profile directory')\n .option('--proxy <url>', 'Proxy server URL')\n .option('--kernel-api-key <key>', 'Browser service API key (or set BROWSER_SERVICE_API_KEY env var)')\n .action(async (opts) => {\n try {\n const result = await harvest({\n query: opts.query,\n location: opts.location,\n gl: opts.gl,\n hl: opts.hl,\n depth: parseInt(opts.depth, 10),\n maxQuestions: parseInt(opts.maxQuestions, 10),\n outputDir: opts.output,\n format: opts.format,\n headless: opts.headless,\n profileDir: opts.profile,\n proxy: opts.proxy,\n kernelApiKey: opts.kernelApiKey ?? browserServiceApiKey(),\n })\n console.log(JSON.stringify({ totalQuestions: result.totalQuestions, outputDir: result.stats.seed }))\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n })\n\nexport async function runCli(): Promise<void> {\n await program.parseAsync()\n}\n","#!/usr/bin/env node\nimport { runCli } from '../src/cli.js'\nrunCli()\n"],"mappings":";;;;;;;;;;;;AAAA,SAAS,eAAe;AAIxB,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,aAAa,EAClB,YAAY,sDAAsD,EAClE,eAAe,uBAAuB,YAAY,EAClD,OAAO,6BAA6B,+DAA+D,EACnG,OAAO,aAAa,uBAAuB,IAAI,EAC/C,OAAO,aAAa,wBAAwB,IAAI,EAChD,OAAO,uBAAuB,oBAAoB,GAAG,EACrD,OAAO,2BAA2B,4BAA4B,KAAK,EACnE,OAAO,sBAAsB,oBAAoB,cAAc,EAC/D,OAAO,yBAAyB,qCAAqC,MAAM,EAC3E,OAAO,cAAc,gCAAgC,KAAK,EAC1D,OAAO,mBAAmB,sCAAsC,EAChE,OAAO,iBAAiB,kBAAkB,EAC1C,OAAO,0BAA0B,kEAAkE,EACnG,OAAO,OAAO,SAAS;AACtB,MAAI;AACF,UAAM,SAAS,MAAM,QAAQ;AAAA,MAC3B,OAAO,KAAK;AAAA,MACZ,UAAU,KAAK;AAAA,MACf,IAAI,KAAK;AAAA,MACT,IAAI,KAAK;AAAA,MACT,OAAO,SAAS,KAAK,OAAO,EAAE;AAAA,MAC9B,cAAc,SAAS,KAAK,cAAc,EAAE;AAAA,MAC5C,WAAW,KAAK;AAAA,MAChB,QAAQ,KAAK;AAAA,MACb,UAAU,KAAK;AAAA,MACf,YAAY,KAAK;AAAA,MACjB,OAAO,KAAK;AAAA,MACZ,cAAc,KAAK,gBAAgB,qBAAqB;AAAA,IAC1D,CAAC;AACD,YAAQ,IAAI,KAAK,UAAU,EAAE,gBAAgB,OAAO,gBAAgB,WAAW,OAAO,MAAM,KAAK,CAAC,CAAC;AAAA,EACrG,SAAS,KAAK;AACZ,YAAQ,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAC9D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,eAAsB,SAAwB;AAC5C,QAAM,QAAQ,WAAW;AAC3B;;;AC5CA,OAAO;","names":[]}
1
+ {"version":3,"sources":["../../src/cli.ts","../../bin/paa-harvest.ts"],"sourcesContent":["import { Command } from 'commander'\nimport { browserServiceApiKey } from './lib/browser-service-env.js'\nimport { harvest } from './harvest.js'\n\nconst program = new Command()\n\nprogram\n .name('paa-harvest')\n .description('Recursively extract Google People Also Ask questions')\n .requiredOption('-q, --query <query>', 'Seed query')\n .option('-l, --location <location>', 'Location name (e.g. \"austin\" or \"Austin,Texas,United States\")')\n .option('--gl <gl>', 'Google country code', 'us')\n .option('--hl <hl>', 'Google language code', 'en')\n .option('-d, --depth <depth>', 'BFS depth (1-30)', '3')\n .option('-m, --max-questions <n>', 'Max questions to harvest', '100')\n .option('-o, --output <dir>', 'Output directory', './paa-output')\n .option('-f, --format <format>', 'Output format: json, csv, or both', 'both')\n .option('--headless', 'Run browser in headless mode', false)\n .option('--profile <dir>', 'Persistent browser profile directory')\n .option('--proxy <url>', 'Proxy server URL')\n .option('--kernel-api-key <key>', 'Browser service API key (or set BROWSER_SERVICE_API_KEY env var)')\n .action(async (opts) => {\n try {\n const result = await harvest({\n query: opts.query,\n location: opts.location,\n gl: opts.gl,\n hl: opts.hl,\n depth: parseInt(opts.depth, 10),\n maxQuestions: parseInt(opts.maxQuestions, 10),\n outputDir: opts.output,\n format: opts.format,\n headless: opts.headless,\n profileDir: opts.profile,\n proxy: opts.proxy,\n kernelApiKey: opts.kernelApiKey ?? browserServiceApiKey(),\n })\n console.log(JSON.stringify({ totalQuestions: result.totalQuestions, outputDir: result.stats.seed }))\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n })\n\nexport async function runCli(): Promise<void> {\n await program.parseAsync()\n}\n","#!/usr/bin/env node\nimport { runCli } from '../src/cli.js'\nrunCli()\n"],"mappings":";;;;;;;;;;;;;AAAA,SAAS,eAAe;AAIxB,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,aAAa,EAClB,YAAY,sDAAsD,EAClE,eAAe,uBAAuB,YAAY,EAClD,OAAO,6BAA6B,+DAA+D,EACnG,OAAO,aAAa,uBAAuB,IAAI,EAC/C,OAAO,aAAa,wBAAwB,IAAI,EAChD,OAAO,uBAAuB,oBAAoB,GAAG,EACrD,OAAO,2BAA2B,4BAA4B,KAAK,EACnE,OAAO,sBAAsB,oBAAoB,cAAc,EAC/D,OAAO,yBAAyB,qCAAqC,MAAM,EAC3E,OAAO,cAAc,gCAAgC,KAAK,EAC1D,OAAO,mBAAmB,sCAAsC,EAChE,OAAO,iBAAiB,kBAAkB,EAC1C,OAAO,0BAA0B,kEAAkE,EACnG,OAAO,OAAO,SAAS;AACtB,MAAI;AACF,UAAM,SAAS,MAAM,QAAQ;AAAA,MAC3B,OAAO,KAAK;AAAA,MACZ,UAAU,KAAK;AAAA,MACf,IAAI,KAAK;AAAA,MACT,IAAI,KAAK;AAAA,MACT,OAAO,SAAS,KAAK,OAAO,EAAE;AAAA,MAC9B,cAAc,SAAS,KAAK,cAAc,EAAE;AAAA,MAC5C,WAAW,KAAK;AAAA,MAChB,QAAQ,KAAK;AAAA,MACb,UAAU,KAAK;AAAA,MACf,YAAY,KAAK;AAAA,MACjB,OAAO,KAAK;AAAA,MACZ,cAAc,KAAK,gBAAgB,qBAAqB;AAAA,IAC1D,CAAC;AACD,YAAQ,IAAI,KAAK,UAAU,EAAE,gBAAgB,OAAO,gBAAgB,WAAW,OAAO,MAAM,KAAK,CAAC,CAAC;AAAA,EACrG,SAAS,KAAK;AACZ,YAAQ,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAC9D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,eAAsB,SAAwB;AAC5C,QAAM,QAAQ,WAAW;AAC3B;;;AC5CA,OAAO;","names":[]}