@maestrogtm/maestro-gtm 0.10.16

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 (115) hide show
  1. package/dist/ai-RNHSWSNV.js +158 -0
  2. package/dist/ai-RNHSWSNV.js.map +1 -0
  3. package/dist/app-PSZH2J56.js +54 -0
  4. package/dist/app-PSZH2J56.js.map +1 -0
  5. package/dist/batch-ZCHN54YJ.js +28 -0
  6. package/dist/batch-ZCHN54YJ.js.map +1 -0
  7. package/dist/campaign-XDXQA7KX.js +119 -0
  8. package/dist/campaign-XDXQA7KX.js.map +1 -0
  9. package/dist/chunk-365Q36GF.js +54 -0
  10. package/dist/chunk-365Q36GF.js.map +1 -0
  11. package/dist/chunk-4IV6QS4U.js +122 -0
  12. package/dist/chunk-4IV6QS4U.js.map +1 -0
  13. package/dist/chunk-6GLLK5KO.js +64 -0
  14. package/dist/chunk-6GLLK5KO.js.map +1 -0
  15. package/dist/chunk-6UNBW5SN.js +686 -0
  16. package/dist/chunk-6UNBW5SN.js.map +1 -0
  17. package/dist/chunk-A7JD6EYV.js +92 -0
  18. package/dist/chunk-A7JD6EYV.js.map +1 -0
  19. package/dist/chunk-ARNVJPFM.js +139 -0
  20. package/dist/chunk-ARNVJPFM.js.map +1 -0
  21. package/dist/chunk-AX6BOEF2.js +345 -0
  22. package/dist/chunk-AX6BOEF2.js.map +1 -0
  23. package/dist/chunk-C3T7QPSO.js +507 -0
  24. package/dist/chunk-C3T7QPSO.js.map +1 -0
  25. package/dist/chunk-FG43GILY.js +46 -0
  26. package/dist/chunk-FG43GILY.js.map +1 -0
  27. package/dist/chunk-FS6DCNCA.js +139 -0
  28. package/dist/chunk-FS6DCNCA.js.map +1 -0
  29. package/dist/chunk-I6GRD4X7.js +1144 -0
  30. package/dist/chunk-I6GRD4X7.js.map +1 -0
  31. package/dist/chunk-IP34URKR.js +621 -0
  32. package/dist/chunk-IP34URKR.js.map +1 -0
  33. package/dist/chunk-JFSKOY7Z.js +252 -0
  34. package/dist/chunk-JFSKOY7Z.js.map +1 -0
  35. package/dist/chunk-M25KLO7T.js +3272 -0
  36. package/dist/chunk-M25KLO7T.js.map +1 -0
  37. package/dist/chunk-M3G2WREL.js +57 -0
  38. package/dist/chunk-M3G2WREL.js.map +1 -0
  39. package/dist/chunk-MFFACSBE.js +4266 -0
  40. package/dist/chunk-MFFACSBE.js.map +1 -0
  41. package/dist/chunk-PZ5AY32C.js +10 -0
  42. package/dist/chunk-PZ5AY32C.js.map +1 -0
  43. package/dist/chunk-QZH3XFOQ.js +2636 -0
  44. package/dist/chunk-QZH3XFOQ.js.map +1 -0
  45. package/dist/chunk-SPWDMOEU.js +1940 -0
  46. package/dist/chunk-SPWDMOEU.js.map +1 -0
  47. package/dist/chunk-TP3BZDVV.js +28 -0
  48. package/dist/chunk-TP3BZDVV.js.map +1 -0
  49. package/dist/chunk-UBJUBYSQ.js +18 -0
  50. package/dist/chunk-UBJUBYSQ.js.map +1 -0
  51. package/dist/chunk-VNKXGHWY.js +20 -0
  52. package/dist/chunk-VNKXGHWY.js.map +1 -0
  53. package/dist/chunk-WKLCPIFB.js +9862 -0
  54. package/dist/chunk-WKLCPIFB.js.map +1 -0
  55. package/dist/chunk-YV5XOXRQ.js +7 -0
  56. package/dist/chunk-YV5XOXRQ.js.map +1 -0
  57. package/dist/cli-Z3BNNJYQ.js +852 -0
  58. package/dist/cli-Z3BNNJYQ.js.map +1 -0
  59. package/dist/client-Y34LNEWN.js +8 -0
  60. package/dist/client-Y34LNEWN.js.map +1 -0
  61. package/dist/config.js +17 -0
  62. package/dist/config.js.map +1 -0
  63. package/dist/configure-XSENK4X5.js +64 -0
  64. package/dist/configure-XSENK4X5.js.map +1 -0
  65. package/dist/context.js +10 -0
  66. package/dist/context.js.map +1 -0
  67. package/dist/crm-QBNHVBYV.js +86 -0
  68. package/dist/crm-QBNHVBYV.js.map +1 -0
  69. package/dist/dfy-X3OXIYRA.js +356 -0
  70. package/dist/dfy-X3OXIYRA.js.map +1 -0
  71. package/dist/dist-LGCJKGBS.js +121 -0
  72. package/dist/dist-LGCJKGBS.js.map +1 -0
  73. package/dist/engagement-C4U7LPJH.js +463 -0
  74. package/dist/engagement-C4U7LPJH.js.map +1 -0
  75. package/dist/enrich-F5GPVZFE.js +226 -0
  76. package/dist/enrich-F5GPVZFE.js.map +1 -0
  77. package/dist/extract-DS5N6SSJ.js +155 -0
  78. package/dist/extract-DS5N6SSJ.js.map +1 -0
  79. package/dist/feedback-AIXKXNM5.js +51 -0
  80. package/dist/feedback-AIXKXNM5.js.map +1 -0
  81. package/dist/fetch-QJDSPI63.js +87 -0
  82. package/dist/fetch-QJDSPI63.js.map +1 -0
  83. package/dist/handlers.js +13 -0
  84. package/dist/handlers.js.map +1 -0
  85. package/dist/index.js +38 -0
  86. package/dist/index.js.map +1 -0
  87. package/dist/list-HL7NQQJX.js +236 -0
  88. package/dist/list-HL7NQQJX.js.map +1 -0
  89. package/dist/maestro-N7Q2JX22.js +903 -0
  90. package/dist/maestro-N7Q2JX22.js.map +1 -0
  91. package/dist/prospect-RUOT43H6.js +532 -0
  92. package/dist/prospect-RUOT43H6.js.map +1 -0
  93. package/dist/providers/factory.js +10 -0
  94. package/dist/providers/factory.js.map +1 -0
  95. package/dist/providers/registry.js +8 -0
  96. package/dist/providers/registry.js.map +1 -0
  97. package/dist/provision-FT5NWN77.js +394 -0
  98. package/dist/provision-FT5NWN77.js.map +1 -0
  99. package/dist/recipe-JU3SXMZF.js +137 -0
  100. package/dist/recipe-JU3SXMZF.js.map +1 -0
  101. package/dist/review-5SB6DYDZ.js +70 -0
  102. package/dist/review-5SB6DYDZ.js.map +1 -0
  103. package/dist/sdk-LVBHNQ6T.js +3852 -0
  104. package/dist/sdk-LVBHNQ6T.js.map +1 -0
  105. package/dist/server-REKYQZ2E.js +22 -0
  106. package/dist/server-REKYQZ2E.js.map +1 -0
  107. package/dist/status-V3EEFS7S.js +114 -0
  108. package/dist/status-V3EEFS7S.js.map +1 -0
  109. package/dist/tam-J6NDBP5W.js +682 -0
  110. package/dist/tam-J6NDBP5W.js.map +1 -0
  111. package/dist/tools.js +80 -0
  112. package/dist/tools.js.map +1 -0
  113. package/dist/validation.js +12 -0
  114. package/dist/validation.js.map +1 -0
  115. package/package.json +77 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/providers/tam-router.ts","../src/providers/tam-engine.ts","../src/providers/tam-session.ts","../src/handlers/tam.ts"],"sourcesContent":["/** TamRouter. Analyzes ICP to determine provider priority order for TAM building.\n * Constraint: Pure function. No I/O. No registry access. */\n\n// ─── Types ──────────────────────────────────────────────\n\nexport interface TamRouterInput {\n icp_text: string;\n domains?: string[];\n tech_stack?: string[];\n category?: string;\n providers?: string[]; // User override\n}\n\n// ─── Signal Detection ───────────────────────────────────\n\nconst LOCAL_SIGNALS = [\n 'restaurant',\n 'gym',\n 'salon',\n 'studio',\n 'spa',\n 'fitness',\n 'clinic',\n 'dental',\n 'medical',\n 'veterinar',\n 'chiropractic',\n 'retail',\n 'store',\n 'local',\n 'physical',\n 'brick',\n 'mortar',\n 'plumber',\n 'electrician',\n 'contractor',\n 'landscap',\n];\nconst ECOMMERCE_SIGNALS = [\n 'shopify',\n 'ecommerce',\n 'e-commerce',\n 'dtc',\n 'merchant',\n 'online store',\n 'woocommerce',\n 'magento',\n];\nconst SEMANTIC_SIGNALS = [\n 'like',\n 'similar to',\n 'companies that',\n 'not quite',\n 'feel of',\n 'vibe of',\n];\n\nfunction hasSignal(text: string, signals: string[]): boolean {\n const lower = text.toLowerCase();\n return signals.some((s) => lower.includes(s));\n}\n\n// ─── Default Provider Order ─────────────────────────────\n\nconst DEFAULT_ORDER = ['disco', 'apollo', 'exa', 'storeleads', 'hunter'];\n\n// ─── Router ─────────────────────────────────────────────\n\n/** Determine optimal provider order based on ICP analysis.\n * If `input.providers` is set, returns it as-is (user override).\n * Otherwise, analyzes ICP signals to pick the best order.\n * Result is filtered to only providers in `availableProviders`. */\nexport function routeProviders(input: TamRouterInput, availableProviders: string[]): string[] {\n // User override — respect it exactly, but filter to available\n if (input.providers?.length) {\n return input.providers.filter((p) => availableProviders.includes(p));\n }\n\n const text = `${input.icp_text} ${input.category ?? ''}`;\n let order: string[];\n\n if (input.domains?.length) {\n // Lookalike domains → Disco first (best lookalike engine)\n order = ['disco', 'apollo', 'exa', 'storeleads', 'hunter'];\n } else if (hasSignal(text, ECOMMERCE_SIGNALS)) {\n // E-commerce → StoreLeads first (checked before local so \"Shopify stores\" → storeleads)\n order = ['storeleads', 'disco', 'apollo', 'exa', 'hunter'];\n } else if (hasSignal(text, LOCAL_SIGNALS)) {\n // Local/physical businesses → Apify (Google Maps) first\n order = ['apify', 'apollo', 'disco', 'exa', 'hunter'];\n } else if (input.tech_stack?.length) {\n // Tech stack filtering → Disco first (has tech stack data)\n order = ['disco', 'apollo', 'exa', 'storeleads', 'hunter'];\n } else if (hasSignal(text, SEMANTIC_SIGNALS)) {\n // Semantic/abstract queries → Exa first (neural search)\n order = ['exa', 'disco', 'apollo', 'storeleads', 'hunter'];\n } else {\n order = DEFAULT_ORDER;\n }\n\n return order.filter((p) => availableProviders.includes(p));\n}\n","/** TamEngine. Multi-provider company discovery with domain-based dedup and budget tracking.\n * Orchestrates paginated rounds across providers, deduplicating incrementally.\n * Constraint: No database. No filesystem I/O. Uses provider registry for API calls only. */\n\nimport { logError } from '@maestro/logging';\n\nimport type { ProviderRegistry } from './registry.js';\nimport type { CompanyFinder, CompanyQuery, CompanyResult } from './types.js';\nimport { routeProviders } from './tam-router.js';\n\n// ─── Types ──────────────────────────────────────────────\n\nexport interface TamConfig {\n icp_text: string;\n domains?: string[];\n budget_usd?: number;\n providers?: string[];\n max_per_provider?: number;\n limit?: number;\n country?: string;\n min_employees?: number;\n max_employees?: number;\n tech_stack?: string[];\n category?: string;\n negate_domains?: string[];\n}\n\nexport interface TamRound {\n provider: string;\n found: number;\n net_new: number;\n duplicates: number;\n cost_usd: number;\n duration_ms: number;\n error?: string;\n}\n\nexport interface TamResult {\n companies: TamCompany[];\n rounds: TamRound[];\n total_found: number;\n total_unique: number;\n total_cost_usd: number;\n budget_remaining_usd?: number;\n stopped_reason: 'target_reached' | 'budget_exhausted' | 'efficiency_drop' | 'all_providers_done';\n}\n\nexport interface TamCompany extends CompanyResult {\n _provider: string;\n _round: number;\n _cost_usd: number;\n _added_at: string;\n}\n\nexport interface TamDryRunEstimate {\n dry_run: true;\n provider_order: string[];\n estimated_cost_per_provider: Record<\n string,\n { cost_per_company: number; max_companies: number; estimated_cost: number }\n >;\n estimated_total_cost_usd: number;\n limit: number;\n note: string;\n}\n\n/** Dedup state passed from session resume or initialized fresh. */\nexport interface TamDedupSets {\n domains: Set<string>;\n linkedins: Set<string>;\n names: Set<string>;\n}\n\n// ─── Pricing ────────────────────────────────────────────\n\nconst TAM_PRICING: Record<string, number> = {\n disco: 0.01,\n apollo: 0.03,\n exa: 0.01,\n storeleads: 0.0,\n hunter: 0.01,\n apify: 0.0015,\n};\n\n// ─── Provider Limits ────────────────────────────────────\n\nconst PROVIDER_MAX_RESULTS: Record<string, number> = {\n disco: 10000,\n apollo: 2000,\n exa: 1000,\n storeleads: 5000,\n hunter: 1000,\n // Apify cap matches page size — each \"page\" is a full actor run, so pagination\n // would launch redundant paid runs returning duplicate results. Single run only.\n apify: 1000,\n};\n\nconst PROVIDER_PAGE_SIZE: Record<string, number> = {\n disco: 100,\n apollo: 100,\n exa: 100,\n storeleads: 100,\n hunter: 100,\n apify: 1000,\n};\n\n/** Providers that support negate_domains WITH input domains required. */\nconst NEGATE_NEEDS_DOMAINS = new Set(['disco']);\n\n/** Providers that support negate_domains standalone (no input domains needed). */\nconst NEGATE_STANDALONE = new Set(['exa']);\n\n// ─── Circuit Breaker ────────────────────────────────────\n\nconst CIRCUIT_BREAKER_THRESHOLD = 2;\nconst PAGE_TIMEOUT_MS = 30_000;\nconst PAGE_DELAY_MS = 200;\n\n/** Apify runs actors that crawl external sites — much slower than API calls. */\nconst PROVIDER_TIMEOUT_OVERRIDES: Record<string, number> = {\n apify: 180_000, // 3 minutes — actor must start, crawl Google Maps, return dataset\n};\nconst DEFAULT_EFFICIENCY_THRESHOLD = 5; // net-new per $1\n\nconst EXHAUSTION_PATTERNS = [\n 'insufficient credits',\n 'no credits',\n '0 credits',\n 'plan limit',\n 'quota exceeded',\n 'upgrade your plan',\n];\n\nfunction isExhaustedError(error: unknown): boolean {\n const msg = error instanceof Error ? error.message.toLowerCase() : String(error).toLowerCase();\n return EXHAUSTION_PATTERNS.some((p) => msg.includes(p));\n}\n\n// ─── Domain Normalization ───────────────────────────────\n// Copied from @maestro/gtm/tam/tam.helpers.ts\n\nexport function normalizeDomain(raw: string | null | undefined): string | null {\n if (!raw) return null;\n let d = raw.trim().toLowerCase();\n d = d.replace(/^https?:\\/\\//, '');\n d = d.replace(/^www\\./, '');\n d = d.split('/')[0];\n d = d.split(':')[0];\n return d || null;\n}\n\nexport function normalizeName(name: string | undefined): string | null {\n if (!name) return null;\n const result = name\n .toLowerCase()\n .replace(/\\b(inc|corp|corporation|llc|ltd|limited|co|company|group|holdings)\\b\\.?/g, '')\n .replace(/[^a-z0-9]/g, '')\n .trim();\n return result || null;\n}\n\n// ─── Dedup ──────────────────────────────────────────────\n\nfunction isDuplicate(company: CompanyResult, dedup: TamDedupSets): boolean {\n const domain = normalizeDomain(company.domain);\n if (domain && dedup.domains.has(domain)) return true;\n\n const linkedin = company.linkedin_url?.toLowerCase().trim();\n if (linkedin && dedup.linkedins.has(linkedin)) return true;\n\n const name = normalizeName(company.name);\n if (name && dedup.names.has(name)) return true;\n\n return false;\n}\n\nfunction addToDedup(company: CompanyResult, dedup: TamDedupSets): void {\n const domain = normalizeDomain(company.domain);\n if (domain) dedup.domains.add(domain);\n\n const linkedin = company.linkedin_url?.toLowerCase().trim();\n if (linkedin) dedup.linkedins.add(linkedin);\n\n const name = normalizeName(company.name);\n if (name) dedup.names.add(name);\n}\n\n// ─── Timeout ────────────────────────────────────────────\n\nfunction withTimeout<T>(promise: Promise<T>, ms: number, label: string): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(\n () => reject(new Error(`TAM provider timeout: ${label} did not respond within ${ms}ms`)),\n ms\n );\n promise.then(\n (val) => {\n clearTimeout(timer);\n resolve(val);\n },\n (err) => {\n clearTimeout(timer);\n reject(err);\n }\n );\n });\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n// ─── Provider Query Builder ─────────────────────────────\n\n/** Build a provider-optimal CompanyQuery. Each provider interprets query fields differently:\n * Disco: semantic ICP + tech_stack + category. Apollo: keyword tags (adapter tokenizes).\n * StorLeads: search field, not icp_text. Exa: neural search. */\nfunction buildProviderQuery(\n providerName: string,\n config: TamConfig,\n offset: number,\n pageSize: number\n): CompanyQuery {\n const base: CompanyQuery = {\n limit: pageSize,\n offset,\n country: config.country,\n min_employees: config.min_employees,\n max_employees: config.max_employees,\n };\n\n switch (providerName) {\n case 'disco':\n // Disco: tech_stack omitted (API bug — treats values as domains). Category validated in adapter.\n return {\n ...base,\n icp_text: config.icp_text,\n domains: config.domains,\n category: config.category,\n };\n case 'apollo':\n // Apollo: supports tech stack via currently_using_any_of_technology_uids (adapter converts)\n return {\n ...base,\n icp_text: config.icp_text,\n domains: config.domains,\n tech_stack: config.tech_stack,\n };\n case 'exa':\n return { ...base, icp_text: config.icp_text, domains: config.domains };\n case 'hunter':\n return { ...base, icp_text: config.icp_text };\n case 'storeleads':\n return { ...base, search: config.icp_text, category: config.category };\n case 'apify':\n return { ...base, icp_text: config.icp_text, category: config.category };\n default:\n return {\n ...base,\n icp_text: config.icp_text,\n domains: config.domains,\n tech_stack: config.tech_stack,\n category: config.category,\n };\n }\n}\n\n// ─── Engine ─────────────────────────────────────────────\n\nexport async function runTamWaterfall(\n config: TamConfig,\n registry: ProviderRegistry,\n existingSets?: TamDedupSets\n): Promise<TamResult> {\n const limit = config.limit ?? 1000;\n const maxPerProvider = config.max_per_provider ?? 500;\n const budgetUsd = config.budget_usd;\n const efficiencyThreshold = DEFAULT_EFFICIENCY_THRESHOLD;\n\n // Initialize dedup sets\n const dedup: TamDedupSets = existingSets ?? {\n domains: new Set(),\n linkedins: new Set(),\n names: new Set(),\n };\n\n // Add user-specified negate_domains to dedup set\n if (config.negate_domains) {\n for (const d of config.negate_domains) {\n const normalized = normalizeDomain(d);\n if (normalized) dedup.domains.add(normalized);\n }\n }\n\n // Route providers\n const availableProviders = registry.getForCapability('find_companies').map((p) => p.name);\n\n const providerOrder = routeProviders(\n {\n icp_text: config.icp_text,\n domains: config.domains,\n tech_stack: config.tech_stack,\n category: config.category,\n providers: config.providers,\n },\n availableProviders\n );\n\n const allCompanies: TamCompany[] = [];\n const rounds: TamRound[] = [];\n let totalCost = 0;\n let stoppedReason: TamResult['stopped_reason'] = 'all_providers_done';\n\n const exhausted = new Set<string>();\n const consecutiveFailures = new Map<string, number>();\n\n for (const providerName of providerOrder) {\n // Check limit\n if (allCompanies.length >= limit) {\n stoppedReason = 'target_reached';\n break;\n }\n\n // Check budget\n if (budgetUsd !== undefined && totalCost >= budgetUsd) {\n stoppedReason = 'budget_exhausted';\n break;\n }\n\n // Skip exhausted providers\n if (exhausted.has(providerName)) continue;\n\n const provider = registry.get(providerName);\n if (!provider || !('findCompanies' in provider)) continue;\n const finder = provider as unknown as CompanyFinder;\n\n // Pre-validate: Disco requires seed domains for discovery\n if (providerName === 'disco' && !config.domains?.length) {\n rounds.push({\n provider: providerName,\n found: 0,\n net_new: 0,\n duplicates: 0,\n cost_usd: 0,\n duration_ms: 0,\n error: 'Skipped: Disco requires seed domains for discovery',\n });\n continue;\n }\n\n const roundStart = Date.now();\n const pricing = TAM_PRICING[providerName] ?? 0.01;\n const pageSize = PROVIDER_PAGE_SIZE[providerName] ?? 100;\n const maxResults = PROVIDER_MAX_RESULTS[providerName] ?? 5000;\n const roundNumber = rounds.length + 1;\n\n // Calculate how many to fetch this round\n const remainingToLimit = limit - allCompanies.length;\n const remainingBudgetCompanies =\n budgetUsd !== undefined\n ? Math.floor((budgetUsd - totalCost) / Math.max(pricing, 0.001))\n : Infinity;\n const targetForProvider = Math.min(\n maxPerProvider,\n maxResults,\n remainingToLimit,\n remainingBudgetCompanies\n );\n\n if (targetForProvider <= 0) {\n stoppedReason = 'budget_exhausted';\n break;\n }\n\n let roundFound = 0;\n let roundNetNew = 0;\n let roundCost = 0;\n let roundError: string | undefined;\n const roundCompanies: TamCompany[] = [];\n let offset = 0;\n\n // Paginate through provider\n while (offset < targetForProvider) {\n const currentPageSize = Math.min(pageSize, targetForProvider - offset);\n\n // Build provider-specific query\n const query = buildProviderQuery(providerName, config, offset, currentPageSize);\n\n // Pass dedup domains as negate_domains to providers that support it at the API level.\n // Exa supports excludeDomains standalone. Disco requires input domains alongside negate_domain.\n if (NEGATE_STANDALONE.has(providerName) && dedup.domains.size > 0) {\n query.negate_domains = [...(config.negate_domains ?? []), ...dedup.domains];\n } else if (\n NEGATE_NEEDS_DOMAINS.has(providerName) &&\n dedup.domains.size > 0 &&\n config.domains?.length\n ) {\n query.negate_domains = [...(config.negate_domains ?? []), ...dedup.domains];\n } else if (config.negate_domains?.length) {\n query.negate_domains = config.negate_domains;\n }\n\n try {\n const timeoutMs = PROVIDER_TIMEOUT_OVERRIDES[providerName] ?? PAGE_TIMEOUT_MS;\n const pageResults = await withTimeout(\n finder.findCompanies(query),\n timeoutMs,\n `${providerName} page ${Math.floor(offset / pageSize) + 1}`\n );\n\n // Reset circuit breaker on success\n consecutiveFailures.set(providerName, 0);\n\n // Dedup page results\n for (const company of pageResults) {\n roundFound++;\n const pageCost = pricing;\n roundCost += pageCost;\n totalCost += pageCost;\n\n if (!isDuplicate(company, dedup)) {\n roundNetNew++;\n addToDedup(company, dedup);\n const tamCompany: TamCompany = {\n ...company,\n _provider: providerName,\n _round: roundNumber,\n _cost_usd: pageCost,\n _added_at: new Date().toISOString(),\n };\n roundCompanies.push(tamCompany);\n }\n\n // Check budget after each company\n if (budgetUsd !== undefined && totalCost >= budgetUsd) break;\n }\n\n offset += currentPageSize;\n\n // Stop pagination: provider returned fewer results than requested (last page)\n if (pageResults.length < currentPageSize) break;\n\n // Stop pagination: budget exhausted\n if (budgetUsd !== undefined && totalCost >= budgetUsd) break;\n\n // Stop pagination: total limit reached\n if (allCompanies.length + roundCompanies.length >= limit) break;\n\n // Throttle between pages\n if (offset < targetForProvider) {\n await sleep(PAGE_DELAY_MS);\n }\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n\n if (isExhaustedError(error)) {\n exhausted.add(providerName);\n roundError = `Provider exhausted: ${errorMsg}`;\n break;\n }\n\n const failures = (consecutiveFailures.get(providerName) ?? 0) + 1;\n consecutiveFailures.set(providerName, failures);\n\n if (failures >= CIRCUIT_BREAKER_THRESHOLD) {\n exhausted.add(providerName);\n roundError = `Circuit breaker tripped after ${failures} failures: ${errorMsg}`;\n } else {\n roundError = errorMsg;\n }\n\n logError(\n `tam-engine:${providerName}`,\n error instanceof Error ? error : new Error(errorMsg),\n {\n offset,\n roundFound,\n roundNetNew,\n }\n );\n break;\n }\n }\n\n allCompanies.push(...roundCompanies);\n\n rounds.push({\n provider: providerName,\n found: roundFound,\n net_new: roundNetNew,\n duplicates: roundFound - roundNetNew,\n cost_usd: Math.round(roundCost * 10000) / 10000,\n duration_ms: Date.now() - roundStart,\n ...(roundError && { error: roundError }),\n });\n\n // Check efficiency: if this round produced too few net-new per dollar, stop\n if (roundCost > 0 && budgetUsd !== undefined) {\n const efficiency = roundNetNew / roundCost;\n if (efficiency < efficiencyThreshold && rounds.length > 1) {\n stoppedReason = 'efficiency_drop';\n break;\n }\n }\n\n // Recheck budget after round\n if (budgetUsd !== undefined && totalCost >= budgetUsd) {\n stoppedReason = 'budget_exhausted';\n break;\n }\n\n // Recheck limit after round\n if (allCompanies.length >= limit) {\n stoppedReason = 'target_reached';\n break;\n }\n }\n\n return {\n companies: allCompanies,\n rounds,\n total_found: rounds.reduce((sum, r) => sum + r.found, 0),\n total_unique: allCompanies.length,\n total_cost_usd: Math.round(totalCost * 10000) / 10000,\n ...(budgetUsd !== undefined && {\n budget_remaining_usd: Math.round(Math.max(0, budgetUsd - totalCost) * 10000) / 10000,\n }),\n stopped_reason: stoppedReason,\n };\n}\n\n// ─── Dry Run ────────────────────────────────────────────\n\nexport function dryRunTam(config: TamConfig, registry: ProviderRegistry): TamDryRunEstimate {\n const limit = config.limit ?? 1000;\n const maxPerProvider = config.max_per_provider ?? 500;\n\n const availableProviders = registry.getForCapability('find_companies').map((p) => p.name);\n\n const providerOrder = routeProviders(\n {\n icp_text: config.icp_text,\n domains: config.domains,\n tech_stack: config.tech_stack,\n category: config.category,\n providers: config.providers,\n },\n availableProviders\n );\n\n const costs: Record<\n string,\n { cost_per_company: number; max_companies: number; estimated_cost: number }\n > = {};\n let totalEstimate = 0;\n\n for (const name of providerOrder) {\n const pricing = TAM_PRICING[name] ?? 0.01;\n const maxResults = Math.min(maxPerProvider, PROVIDER_MAX_RESULTS[name] ?? 5000);\n const estimatedCost = pricing * maxResults;\n costs[name] = {\n cost_per_company: pricing,\n max_companies: maxResults,\n estimated_cost: Math.round(estimatedCost * 100) / 100,\n };\n totalEstimate += estimatedCost;\n }\n\n return {\n dry_run: true,\n provider_order: providerOrder,\n estimated_cost_per_provider: costs,\n estimated_total_cost_usd: Math.round(totalEstimate * 100) / 100,\n limit,\n note:\n 'Estimates assume max companies per provider with no deduplication savings. ' +\n 'Actual cost is typically 20-40% lower due to cross-provider overlap.',\n };\n}\n","/** TamSession. File-based persistence for TAM discovery sessions.\n * Constraint: Append-only writes. No database. No rewrites. */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as os from 'node:os';\nimport { logWarn } from '@maestro/logging';\nimport { normalizeDomain, normalizeName } from './tam-engine.js';\n\n// ─── Types ──────────────────────────────────────────────\n\nexport interface SessionInit {\n _type: 'init';\n name: string;\n created_at: string;\n icp_text: string;\n budget_usd?: number;\n}\n\nexport interface SessionRound {\n _type: 'round';\n provider: string;\n found: number;\n net_new: number;\n duplicates: number;\n cost_usd: number;\n duration_ms: number;\n total_companies: number;\n total_cost_usd: number;\n timestamp: string;\n}\n\nexport interface SessionCompany {\n _type: 'company';\n domain: string;\n name: string;\n linkedin_url?: string;\n _provider: string;\n _round: number;\n _cost_usd: number;\n [key: string]: unknown;\n}\n\nexport interface SessionMetadata {\n name: string;\n created_at: string;\n icp_text: string;\n budget_usd?: number;\n total_companies: number;\n total_cost_usd: number;\n rounds: SessionRound[];\n}\n\nexport interface SessionState {\n meta: SessionMetadata;\n domains: Set<string>;\n linkedins: Set<string>;\n names: Set<string>;\n}\n\n// ─── Constants ──────────────────────────────────────────\n\nconst SESSIONS_DIR = path.join(os.homedir(), '.gtm', 'tam-sessions');\n\n/** Sanitize session name for use as filename. */\nexport function sanitizeName(name: string): string {\n return name\n .toLowerCase()\n .replace(/[^a-z0-9-_]/g, '-')\n .replace(/-+/g, '-')\n .slice(0, 100);\n}\n\n/** Get the resolved file path for a session. */\nexport function getSessionPath(name: string, dir?: string): string {\n return path.join(dir ?? SESSIONS_DIR, `${sanitizeName(name)}.jsonl`);\n}\n\nfunction ensureDir(dir?: string): void {\n fs.mkdirSync(dir ?? SESSIONS_DIR, { recursive: true });\n}\n\n// ─── Public API ─────────────────────────────────────────\n\n/** Load an existing session. Returns null if not found. */\nexport function loadSession(name: string, sessionsDir?: string): SessionState | null {\n const filePath = getSessionPath(name, sessionsDir);\n if (!fs.existsSync(filePath)) return null;\n\n const content = fs.readFileSync(filePath, 'utf-8');\n const lines = content.trim().split('\\n').filter(Boolean);\n if (lines.length === 0) return null;\n\n let init: SessionInit | null = null;\n const domains = new Set<string>();\n const linkedins = new Set<string>();\n const names = new Set<string>();\n const rounds: SessionRound[] = [];\n let totalCompanies = 0;\n let totalCost = 0;\n\n for (const line of lines) {\n try {\n const parsed = JSON.parse(line) as { _type: string; [key: string]: unknown };\n\n if (parsed._type === 'init') {\n init = parsed as unknown as SessionInit;\n } else if (parsed._type === 'company') {\n const company = parsed as unknown as SessionCompany;\n const normalizedDomain = normalizeDomain(company.domain);\n if (normalizedDomain) domains.add(normalizedDomain);\n if (company.linkedin_url) linkedins.add(company.linkedin_url.toLowerCase().trim());\n if (company.name) {\n const normalized = normalizeName(company.name);\n if (normalized) names.add(normalized);\n }\n } else if (parsed._type === 'round') {\n const round = parsed as unknown as SessionRound;\n rounds.push(round);\n totalCompanies = round.total_companies;\n totalCost = round.total_cost_usd;\n }\n } catch {\n logWarn('tam-session:load', 'Skipped corrupted line in session file', { name });\n }\n }\n\n if (!init) return null;\n\n return {\n meta: {\n name: init.name,\n created_at: init.created_at,\n icp_text: init.icp_text,\n budget_usd: init.budget_usd,\n total_companies: totalCompanies,\n total_cost_usd: totalCost,\n rounds,\n },\n domains,\n linkedins,\n names,\n };\n}\n\n/** Create a new session file. Returns metadata. */\nexport function createSession(\n name: string,\n icp_text: string,\n budget_usd?: number,\n sessionsDir?: string\n): SessionMetadata {\n ensureDir(sessionsDir);\n const filePath = getSessionPath(name, sessionsDir);\n\n if (fs.existsSync(filePath)) {\n logWarn('tam-session:create', `Session file already exists, overwriting: ${filePath}`, {\n name,\n });\n }\n\n const init: SessionInit = {\n _type: 'init',\n name,\n created_at: new Date().toISOString(),\n icp_text,\n budget_usd,\n };\n\n fs.writeFileSync(filePath, JSON.stringify(init) + '\\n', 'utf-8');\n\n return {\n name,\n created_at: init.created_at,\n icp_text,\n budget_usd,\n total_companies: 0,\n total_cost_usd: 0,\n rounds: [],\n };\n}\n\n/** Append companies and a round summary to an existing session. Strictly append-only. */\nexport function appendToSession(\n name: string,\n companies: SessionCompany[],\n round: Omit<SessionRound, '_type' | 'timestamp' | 'total_companies' | 'total_cost_usd'>,\n runningTotals: { total_companies: number; total_cost_usd: number },\n sessionsDir?: string\n): void {\n const filePath = getSessionPath(name, sessionsDir);\n\n const companyLines = companies.map((c) => JSON.stringify({ ...c, _type: 'company' }));\n const roundLine = JSON.stringify({\n ...round,\n _type: 'round',\n total_companies: runningTotals.total_companies,\n total_cost_usd: runningTotals.total_cost_usd,\n timestamp: new Date().toISOString(),\n } satisfies SessionRound);\n\n const content = [...companyLines, roundLine].join('\\n') + '\\n';\n fs.appendFileSync(filePath, content, 'utf-8');\n}\n\n/** List all available sessions with their metadata. */\nexport function listSessions(sessionsDir?: string): SessionMetadata[] {\n const dir = sessionsDir ?? SESSIONS_DIR;\n if (!fs.existsSync(dir)) return [];\n\n const files = fs.readdirSync(dir).filter((f) => f.endsWith('.jsonl'));\n const sessions: SessionMetadata[] = [];\n\n for (const file of files) {\n const name = file.replace('.jsonl', '');\n const state = loadSession(name, sessionsDir);\n if (state) sessions.push(state.meta);\n }\n\n return sessions;\n}\n","/** TAM handler. Orchestrates TAM waterfall with session persistence.\n * Constraint: No direct API calls. Uses tam-engine + tam-session + registry. */\n\nimport type { HandlerContext } from './index.js';\nimport { runTamWaterfall, dryRunTam } from '../providers/tam-engine.js';\nimport type { TamConfig, TamDedupSets } from '../providers/tam-engine.js';\nimport {\n loadSession,\n createSession,\n appendToSession,\n getSessionPath,\n} from '../providers/tam-session.js';\nimport type { SessionCompany } from '../providers/tam-session.js';\nimport { writeResultsFile } from '../utils/result-writer.js';\n\n// ─── Handler ────────────────────────────────────────────\n\nexport async function handleTam(\n args: Record<string, unknown>,\n ctx: HandlerContext\n): Promise<unknown> {\n const config: TamConfig = {\n icp_text: args.icp_text as string,\n domains: args.domains as string[] | undefined,\n budget_usd: args.budget_usd as number | undefined,\n providers: args.providers as string[] | undefined,\n max_per_provider: args.max_per_provider as number | undefined,\n limit: args.limit as number | undefined,\n country: args.country as string | undefined,\n min_employees: args.min_employees as number | undefined,\n max_employees: args.max_employees as number | undefined,\n tech_stack: args.tech_stack as string[] | undefined,\n category: args.category as string | undefined,\n negate_domains: args.negate_domains as string[] | undefined,\n };\n\n const sessionName = args.session as string | undefined;\n const output = (args.output as string) ?? 'summary';\n const dryRun = args.dry_run as boolean | undefined;\n\n // ─── Dry Run ────────────────────────────────────────\n\n if (dryRun) {\n return dryRunTam(config, ctx.registry);\n }\n\n // ─── Session Resume ─────────────────────────────────\n\n let existingSets: TamDedupSets | undefined;\n let sessionTotalCompanies = 0;\n let sessionTotalCost = 0;\n\n if (sessionName) {\n const existing = loadSession(sessionName);\n if (existing) {\n existingSets = {\n domains: existing.domains,\n linkedins: existing.linkedins,\n names: existing.names,\n };\n sessionTotalCompanies = existing.meta.total_companies;\n sessionTotalCost = existing.meta.total_cost_usd;\n\n // Adjust budget for already-spent amount\n if (config.budget_usd !== undefined) {\n config.budget_usd = Math.max(0, config.budget_usd - sessionTotalCost);\n }\n } else {\n createSession(sessionName, config.icp_text, args.budget_usd as number | undefined);\n }\n }\n\n // ─── Run Engine ─────────────────────────────────────\n\n const result = await runTamWaterfall(config, ctx.registry, existingSets);\n\n // ─── Persist to Session ─────────────────────────────\n\n if (sessionName) {\n const sessionCompanies: SessionCompany[] = result.companies.map((c) => ({\n _type: 'company' as const,\n domain: c.domain,\n name: c.name,\n linkedin_url: c.linkedin_url,\n _provider: c._provider,\n _round: c._round,\n _cost_usd: c._cost_usd,\n description: c.description,\n industry: c.industry,\n employees: c.employees,\n country: c.country,\n }));\n\n // Append companies and round summaries\n for (const round of result.rounds) {\n const roundCompanies = sessionCompanies.filter((c) => c._provider === round.provider);\n sessionTotalCompanies += round.net_new;\n sessionTotalCost += round.cost_usd;\n appendToSession(sessionName, roundCompanies, round, {\n total_companies: sessionTotalCompanies,\n total_cost_usd: sessionTotalCost,\n });\n }\n }\n\n // ─── Format Response ────────────────────────────────\n\n const sessionFilePath = sessionName ? getSessionPath(sessionName) : undefined;\n\n if (output === 'inline' && result.companies.length <= 200) {\n return {\n ...(sessionName && { session: sessionName, session_file: sessionFilePath }),\n rounds: result.rounds,\n total_unique: result.total_unique,\n total_cost_usd: result.total_cost_usd,\n budget_remaining_usd: result.budget_remaining_usd,\n stopped_reason: result.stopped_reason,\n companies: result.companies,\n };\n }\n\n if (output === 'file' || (output === 'inline' && result.companies.length > 200)) {\n const filePath = writeResultsFile('tam-build', result.companies, {\n query: { icp_text: config.icp_text },\n provider: 'waterfall',\n count: result.total_unique,\n has_more: false,\n });\n\n return {\n ...(sessionName && { session: sessionName, session_file: sessionFilePath }),\n rounds: result.rounds,\n total_unique: result.total_unique,\n total_cost_usd: result.total_cost_usd,\n budget_remaining_usd: result.budget_remaining_usd,\n stopped_reason: result.stopped_reason,\n file: filePath,\n preview: result.companies.slice(0, 5).map((c) => ({\n domain: c.domain,\n name: c.name,\n industry: c.industry,\n employees: c.employees,\n _provider: c._provider,\n })),\n };\n }\n\n // Default: summary\n return {\n ...(sessionName && { session: sessionName, session_file: sessionFilePath }),\n rounds: result.rounds,\n total_unique: result.total_unique,\n total_cost_usd: result.total_cost_usd,\n budget_remaining_usd: result.budget_remaining_usd,\n stopped_reason: result.stopped_reason,\n dedup_stats: {\n total_pulled: result.total_found,\n duplicates_removed: result.total_found - result.total_unique,\n dedup_rate:\n result.total_found > 0\n ? `${Math.round(((result.total_found - result.total_unique) / result.total_found) * 100)}%`\n : '0%',\n },\n preview: result.companies.slice(0, 5).map((c) => ({\n domain: c.domain,\n name: c.name,\n industry: c.industry,\n employees: c.employees,\n _provider: c._provider,\n })),\n };\n}\n"],"mappings":"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","names":[]}
package/dist/tools.js ADDED
@@ -0,0 +1,80 @@
1
+ import {
2
+ TOOL_DESCRIPTIONS,
3
+ aiTools,
4
+ analyticsTools,
5
+ batchTools,
6
+ buildCatalogText,
7
+ campaignTools,
8
+ configureTools,
9
+ crmTools,
10
+ dfyTools,
11
+ dmCoachTools,
12
+ emailSequenceTools,
13
+ engagementTools,
14
+ enrichTools,
15
+ exploitTools,
16
+ extractTools,
17
+ fetchTools,
18
+ funnelTools,
19
+ knowledgeTools,
20
+ launchTools,
21
+ leadsTools,
22
+ listTools,
23
+ maestroTools,
24
+ magnetTools,
25
+ mcpTools,
26
+ mixerTools,
27
+ modeTools,
28
+ postTools,
29
+ prospectTools,
30
+ provisionTools,
31
+ recipeTools,
32
+ reviewTools,
33
+ statusTools,
34
+ tamTools,
35
+ toolCategories,
36
+ tools,
37
+ toolsByName,
38
+ workflowRecipes
39
+ } from "./chunk-M25KLO7T.js";
40
+ import "./chunk-PZ5AY32C.js";
41
+ export {
42
+ TOOL_DESCRIPTIONS,
43
+ aiTools,
44
+ analyticsTools,
45
+ batchTools,
46
+ buildCatalogText,
47
+ campaignTools,
48
+ configureTools,
49
+ crmTools,
50
+ dfyTools,
51
+ dmCoachTools,
52
+ emailSequenceTools,
53
+ engagementTools,
54
+ enrichTools,
55
+ exploitTools,
56
+ extractTools,
57
+ fetchTools,
58
+ funnelTools,
59
+ knowledgeTools,
60
+ launchTools,
61
+ leadsTools,
62
+ listTools,
63
+ maestroTools,
64
+ magnetTools,
65
+ mcpTools,
66
+ mixerTools,
67
+ modeTools,
68
+ postTools,
69
+ prospectTools,
70
+ provisionTools,
71
+ recipeTools,
72
+ reviewTools,
73
+ statusTools,
74
+ tamTools,
75
+ toolCategories,
76
+ tools,
77
+ toolsByName,
78
+ workflowRecipes
79
+ };
80
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,12 @@
1
+ import {
2
+ TOOL_NAMES,
3
+ toolSchemas,
4
+ validateToolArgs
5
+ } from "./chunk-I6GRD4X7.js";
6
+ import "./chunk-PZ5AY32C.js";
7
+ export {
8
+ TOOL_NAMES,
9
+ toolSchemas,
10
+ validateToolArgs
11
+ };
12
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/package.json ADDED
@@ -0,0 +1,77 @@
1
+ {
2
+ "name": "@maestrogtm/maestro-gtm",
3
+ "version": "0.10.16",
4
+ "description": "MCP server for GTM operations — cold email, LinkedIn outreach, CRM, enrichment, and TAM discovery",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./dist/index.js"
10
+ },
11
+ "./handlers": {
12
+ "import": "./dist/handlers.js"
13
+ },
14
+ "./tools": {
15
+ "import": "./dist/tools.js"
16
+ },
17
+ "./validation": {
18
+ "import": "./dist/validation.js"
19
+ },
20
+ "./providers/registry": {
21
+ "import": "./dist/providers/registry.js"
22
+ },
23
+ "./providers/factory": {
24
+ "import": "./dist/providers/factory.js"
25
+ },
26
+ "./config": {
27
+ "import": "./dist/config.js"
28
+ },
29
+ "./context": {
30
+ "import": "./dist/context.js"
31
+ }
32
+ },
33
+ "bin": {
34
+ "maestro": "./dist/index.js"
35
+ },
36
+ "files": [
37
+ "dist",
38
+ "README.md"
39
+ ],
40
+ "scripts": {
41
+ "build": "tsup",
42
+ "build:types": "tsc",
43
+ "dev": "tsc --watch",
44
+ "typecheck": "tsc --noEmit",
45
+ "test": "vitest run",
46
+ "test:watch": "vitest",
47
+ "prepublishOnly": "pnpm run build"
48
+ },
49
+ "keywords": [
50
+ "mcp",
51
+ "model-context-protocol",
52
+ "gtm",
53
+ "cold-email",
54
+ "outreach",
55
+ "crm",
56
+ "enrichment",
57
+ "sales"
58
+ ],
59
+ "license": "MIT",
60
+ "dependencies": {
61
+ "@modelcontextprotocol/sdk": "^1.0.0",
62
+ "@supabase/supabase-js": "^2.99.1",
63
+ "commander": "^12.0.0",
64
+ "yaml": "^2.4.0",
65
+ "zod": "^3.23.8"
66
+ },
67
+ "devDependencies": {
68
+ "@maestro/gtm": "workspace:*",
69
+ "@maestro/integrations": "workspace:*",
70
+ "@maestro/knowledge-graph": "workspace:*",
71
+ "@maestro/logging": "workspace:*",
72
+ "tsup": "^8.5.1",
73
+ "tsx": "^4.21.0",
74
+ "typescript": "^5.6.2",
75
+ "vitest": "^3.0.0"
76
+ }
77
+ }