mcp-scraper 0.4.3 → 0.4.4

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 (32) hide show
  1. package/dist/bin/api-server.cjs +2134 -1821
  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 +1 -1
  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 +71 -1
  11. package/dist/bin/mcp-stdio-server.cjs.map +1 -1
  12. package/dist/bin/mcp-stdio-server.js +2 -2
  13. package/dist/{chunk-NVUBFCJK.js → chunk-4ZZWFI6L.js} +2 -2
  14. package/dist/{chunk-4MFYMUIF.js → chunk-5LO6EHEH.js} +25 -3
  15. package/dist/chunk-5LO6EHEH.js.map +1 -0
  16. package/dist/chunk-TZRPP45I.js +7 -0
  17. package/dist/chunk-TZRPP45I.js.map +1 -0
  18. package/dist/{chunk-BAMVP57P.js → chunk-Z34NGK64.js} +72 -2
  19. package/dist/chunk-Z34NGK64.js.map +1 -0
  20. package/dist/{server-LBEYRKM2.js → server-IKT3QVFB.js} +405 -198
  21. package/dist/server-IKT3QVFB.js.map +1 -0
  22. package/dist/{site-extract-repository-4NVO5KQA.js → site-extract-repository-THBVEXMP.js} +3 -3
  23. package/dist/{worker-7XRZNLKB.js → worker-YHKUJR5P.js} +2 -2
  24. package/package.json +1 -1
  25. package/dist/chunk-4MFYMUIF.js.map +0 -1
  26. package/dist/chunk-BAMVP57P.js.map +0 -1
  27. package/dist/chunk-SRMGSCC3.js +0 -7
  28. package/dist/chunk-SRMGSCC3.js.map +0 -1
  29. package/dist/server-LBEYRKM2.js.map +0 -1
  30. /package/dist/{chunk-NVUBFCJK.js.map → chunk-4ZZWFI6L.js.map} +0 -0
  31. /package/dist/{site-extract-repository-4NVO5KQA.js.map → site-extract-repository-THBVEXMP.js.map} +0 -0
  32. /package/dist/{worker-7XRZNLKB.js.map → worker-YHKUJR5P.js.map} +0 -0
@@ -31,7 +31,7 @@ import {
31
31
  registerSerpIntelligenceCaptureTools,
32
32
  sanitizeAttempts,
33
33
  sanitizeHarvestResult
34
- } from "./chunk-BAMVP57P.js";
34
+ } from "./chunk-Z34NGK64.js";
35
35
  import {
36
36
  auditImages,
37
37
  getBlobStore
@@ -65,7 +65,7 @@ import {
65
65
  RawMapsOverviewSchema,
66
66
  RawMapsReviewStatsSchema
67
67
  } from "./chunk-XGIPATLV.js";
68
- import "./chunk-SRMGSCC3.js";
68
+ import "./chunk-TZRPP45I.js";
69
69
  import {
70
70
  completeExtractJob,
71
71
  countSuccessfulPages,
@@ -76,7 +76,7 @@ import {
76
76
  saveExtractPages,
77
77
  setExtractJobTotal,
78
78
  settleExtractJob
79
- } from "./chunk-NVUBFCJK.js";
79
+ } from "./chunk-4ZZWFI6L.js";
80
80
  import {
81
81
  BROWSER_OPEN_MIN_BALANCE_MC,
82
82
  CONCURRENCY_PRICE_ID,
@@ -95,7 +95,7 @@ import {
95
95
  browserActiveCostMc,
96
96
  concurrencySlotBillingInfo,
97
97
  insufficientBalanceResponse
98
- } from "./chunk-4MFYMUIF.js";
98
+ } from "./chunk-5LO6EHEH.js";
99
99
  import {
100
100
  CaptchaError,
101
101
  RECAPTCHA_INSTRUCTIONS,
@@ -5274,7 +5274,7 @@ async function extractSite(opts) {
5274
5274
  }
5275
5275
 
5276
5276
  // src/api/server.ts
5277
- import { Hono as Hono21 } from "hono";
5277
+ import { Hono as Hono22 } from "hono";
5278
5278
  import { serve as serveInngest } from "inngest/hono";
5279
5279
 
5280
5280
  // src/inngest/client.ts
@@ -13310,13 +13310,219 @@ trustpilotApp.post("/reviews", createApiKeyAuth(), async (c) => {
13310
13310
  }
13311
13311
  });
13312
13312
 
13313
- // src/api/directory-routes.ts
13313
+ // src/api/g2-routes.ts
13314
13314
  import { Hono as Hono12 } from "hono";
13315
+ import { z as z20 } from "zod";
13316
+ var G2ReviewsBodySchema = z20.object({
13317
+ product: z20.string().trim().min(1, "product is required"),
13318
+ maxPages: z20.number().int().min(1).max(50).default(5)
13319
+ });
13320
+ function invalidRequest7(message) {
13321
+ return { error_code: "invalid_request", message };
13322
+ }
13323
+ function normalizeProductSlug(input) {
13324
+ return input.trim().replace(/^https?:\/\/(www\.)?g2\.com\/products\//i, "").replace(/\/.*$/, "").replace(/\s+/g, "-").toLowerCase();
13325
+ }
13326
+ function reviewPageUrl2(product, page) {
13327
+ const base = `https://www.g2.com/products/${encodeURIComponent(product)}/reviews`;
13328
+ return page <= 1 ? base : `${base}?page=${page}`;
13329
+ }
13330
+ async function residentialProxyId2(attemptIndex) {
13331
+ try {
13332
+ const r = await resolveKernelProxyId({
13333
+ kernelApiKey: browserServiceApiKey(),
13334
+ proxyMode: "location",
13335
+ location: "Austin, TX",
13336
+ gl: "us",
13337
+ attemptIndex,
13338
+ fresh: true
13339
+ });
13340
+ return r.kernelProxyId;
13341
+ } catch {
13342
+ return void 0;
13343
+ }
13344
+ }
13345
+ async function extractG2ReviewCards(page) {
13346
+ return page.evaluate(() => {
13347
+ const cards = Array.from(document.querySelectorAll("article[data-track-in-viewport-options]"));
13348
+ return cards.map((card) => {
13349
+ let meta = {};
13350
+ try {
13351
+ meta = JSON.parse(card.getAttribute("data-track-in-viewport-options") ?? "{}");
13352
+ } catch {
13353
+ meta = {};
13354
+ }
13355
+ const reviewId = meta.survey_response_id != null ? String(meta.survey_response_id) : null;
13356
+ const publishedDateRaw = typeof meta.published_date === "string" ? meta.published_date : null;
13357
+ const date = publishedDateRaw && /^\d{8}$/.test(publishedDateRaw) ? `${publishedDateRaw.slice(0, 4)}-${publishedDateRaw.slice(4, 6)}-${publishedDateRaw.slice(6, 8)}` : null;
13358
+ const profileLink = card.querySelector('a[href*="/users/"]');
13359
+ const profileHref = profileLink?.getAttribute("href") ?? "";
13360
+ const profileMatch = profileHref.match(/\/users\/([a-f0-9-]+)/i);
13361
+ const profileId = profileMatch ? profileMatch[1] : null;
13362
+ const infoWrapper = profileLink?.parentElement;
13363
+ const infoDiv = infoWrapper ? Array.from(infoWrapper.children).find((el2) => el2 !== profileLink) : null;
13364
+ const name = infoDiv?.querySelector('div[class*="font-bold"]')?.textContent?.trim() ?? null;
13365
+ const subtleDivs = infoDiv ? Array.from(infoDiv.querySelectorAll('div[class*="text-subtle"]')) : [];
13366
+ const reviewerTitle = subtleDivs[0]?.textContent?.trim() ?? null;
13367
+ const companySegment = subtleDivs[1]?.textContent?.trim() ?? null;
13368
+ const ratingEl = card.querySelector('[class*="star-wrapper__desc__rating"]');
13369
+ const ratingText = ratingEl?.textContent?.trim() ?? "";
13370
+ const ratingParts = ratingText.split("/");
13371
+ const rating = ratingParts[0] ? parseFloat(ratingParts[0]) : null;
13372
+ const ratingScale = ratingParts[1] ? parseFloat(ratingParts[1]) : 5;
13373
+ const titleEl = card.querySelector('div[class*="text-lg"][class*="font-bold"]');
13374
+ const title = titleEl?.textContent?.trim().replace(/^["“]+|["”]+$/g, "") ?? null;
13375
+ const sections = Array.from(card.querySelectorAll("section"));
13376
+ const body = sections.map((sec) => {
13377
+ const question = sec.querySelector('div[class*="font-bold"]')?.textContent?.trim() ?? null;
13378
+ const paragraphs = Array.from(sec.querySelectorAll("p")).map((p) => p.textContent?.trim() ?? "");
13379
+ const answer = paragraphs.join("\n\n").replace(/Review collected by and hosted on G2\.com\.\s*$/, "").trim();
13380
+ return { question, answer };
13381
+ }).filter((b) => b.answer.length > 0);
13382
+ const flagButtons = Array.from(card.querySelectorAll("button[title]"));
13383
+ let currentUser = false;
13384
+ let validated = false;
13385
+ let incentivized = false;
13386
+ let origin = null;
13387
+ for (const btn of flagButtons) {
13388
+ const label = btn.querySelector("label")?.textContent?.trim() ?? "";
13389
+ if (/current user/i.test(label)) currentUser = true;
13390
+ else if (/validated/i.test(label)) validated = true;
13391
+ else if (/^incentivized$/i.test(label)) incentivized = true;
13392
+ else if (/^source:/i.test(label)) origin = label.replace(/^source:\s*/i, "").trim();
13393
+ }
13394
+ const copyBtn = card.querySelector('[data-clipboard-text*="/reviews/"]');
13395
+ const reviewUrl = copyBtn?.getAttribute("data-clipboard-text") ?? null;
13396
+ return {
13397
+ source: "g2",
13398
+ sourceReviewId: reviewId,
13399
+ reviewUrl,
13400
+ reviewer: {
13401
+ name,
13402
+ profileId,
13403
+ title: reviewerTitle,
13404
+ companySegment
13405
+ },
13406
+ rating,
13407
+ ratingScale,
13408
+ title,
13409
+ date,
13410
+ body: body.length > 0 ? body : [{ question: null, answer: "" }],
13411
+ truncated: false,
13412
+ flags: {
13413
+ origin,
13414
+ incentivized,
13415
+ validated,
13416
+ currentUser,
13417
+ companyReplied: null
13418
+ }
13419
+ };
13420
+ });
13421
+ });
13422
+ }
13423
+ var g2App = new Hono12();
13424
+ g2App.post("/reviews", createApiKeyAuth(), async (c) => {
13425
+ const raw = await c.req.json().catch(() => ({}));
13426
+ const parsed = G2ReviewsBodySchema.safeParse(raw);
13427
+ if (!parsed.success) return c.json(invalidRequest7(parsed.error.issues[0]?.message ?? "Invalid request"), 400);
13428
+ const body = parsed.data;
13429
+ const product = normalizeProductSlug(body.product);
13430
+ const user = c.get("user");
13431
+ const gate = await acquireConcurrencyGate(user, "g2_reviews", {
13432
+ reuseLockId: c.req.header("x-mcp-scraper-concurrency-lock"),
13433
+ metadata: { product, maxPages: body.maxPages }
13434
+ });
13435
+ if (!gate.ok) return c.json(concurrencyLimitExceededResponse(gate), 429, { "Retry-After": String(gate.retryAfterSeconds) });
13436
+ let debited = false;
13437
+ let reviewDebitMc = 0;
13438
+ try {
13439
+ const { ok, balance_mc } = await debitMc(user.id, MC_COSTS.g2_reviews, LedgerOperation.G2_REVIEWS, product);
13440
+ if (!ok) return c.json(insufficientBalanceResponse(balance_mc, MC_COSTS.g2_reviews), 402);
13441
+ debited = true;
13442
+ const startMs = Date.now();
13443
+ const allReviews = [];
13444
+ let pagesFetched = 0;
13445
+ let blocked = false;
13446
+ for (let attempt = 0; attempt < 3 && pagesFetched === 0; attempt++) {
13447
+ const proxyId = await residentialProxyId2(attempt);
13448
+ const driver = new BrowserDriver();
13449
+ try {
13450
+ await driver.launch({
13451
+ headless: true,
13452
+ kernelApiKey: browserServiceApiKey(),
13453
+ kernelProxyId: proxyId,
13454
+ viewport: { width: 1280, height: 900 },
13455
+ locale: "en-US"
13456
+ });
13457
+ const page = driver.getPage();
13458
+ for (let pageNum = 1; pageNum <= body.maxPages; pageNum++) {
13459
+ const url = reviewPageUrl2(product, pageNum);
13460
+ await page.goto(url, { waitUntil: "domcontentloaded", timeout: 45e3 });
13461
+ await page.waitForTimeout(5e3);
13462
+ await page.evaluate(() => window.scrollTo(0, 1200)).catch(() => {
13463
+ });
13464
+ await page.waitForTimeout(3e3);
13465
+ let cards;
13466
+ try {
13467
+ cards = await extractG2ReviewCards(page);
13468
+ } catch {
13469
+ await page.waitForTimeout(3e3);
13470
+ cards = await extractG2ReviewCards(page);
13471
+ }
13472
+ if (cards.length === 0) break;
13473
+ allReviews.push(...cards);
13474
+ pagesFetched = pageNum;
13475
+ }
13476
+ } catch {
13477
+ blocked = true;
13478
+ } finally {
13479
+ await driver.close();
13480
+ }
13481
+ }
13482
+ if (pagesFetched === 0 || allReviews.length === 0) {
13483
+ await creditMc(user.id, MC_COSTS.g2_reviews, LedgerOperation.G2_REVIEWS_REFUND, blocked ? "blocked after retries" : "no reviews found");
13484
+ await logRequestEvent({ userId: user.id, source: "g2_reviews", status: "failed", query: product, error: blocked ? "blocked after retries" : "no reviews found" });
13485
+ return c.json({ error: "No reviews found for this product (refunded)", product }, 404);
13486
+ }
13487
+ reviewDebitMc = allReviews.length * MC_COSTS.g2_review;
13488
+ if (reviewDebitMc > 0) {
13489
+ const reviewDebit = await debitMc(user.id, reviewDebitMc, LedgerOperation.G2_REVIEW, product);
13490
+ if (!reviewDebit.ok) {
13491
+ allReviews.length = Math.floor((reviewDebit.balance_mc ?? 0) / MC_COSTS.g2_review);
13492
+ reviewDebitMc = allReviews.length * MC_COSTS.g2_review;
13493
+ if (reviewDebitMc > 0) await debitMc(user.id, reviewDebitMc, LedgerOperation.G2_REVIEW, product);
13494
+ }
13495
+ }
13496
+ const result = {
13497
+ product,
13498
+ reviewUrl: reviewPageUrl2(product, 1),
13499
+ extractedAt: (/* @__PURE__ */ new Date()).toISOString(),
13500
+ requestedMaxPages: body.maxPages,
13501
+ pagesFetched,
13502
+ reviewCount: allReviews.length,
13503
+ reviews: allReviews,
13504
+ durationMs: Date.now() - startMs
13505
+ };
13506
+ await logRequestEvent({ userId: user.id, source: "g2_reviews", status: "done", query: product, resultCount: allReviews.length, result });
13507
+ return c.json(result);
13508
+ } catch (err) {
13509
+ if (debited) await creditMc(user.id, MC_COSTS.g2_reviews, LedgerOperation.G2_REVIEWS_REFUND, "failed call");
13510
+ if (reviewDebitMc > 0) await creditMc(user.id, reviewDebitMc, LedgerOperation.G2_REVIEW_REFUND, "failed call");
13511
+ const msg = err instanceof Error ? err.message : String(err);
13512
+ await logRequestEvent({ userId: user.id, source: "g2_reviews", status: "failed", query: product, error: msg });
13513
+ return c.json({ error: msg }, 500);
13514
+ } finally {
13515
+ await releaseConcurrencyGate(gate.lockId);
13516
+ }
13517
+ });
13518
+
13519
+ // src/api/directory-routes.ts
13520
+ import { Hono as Hono13 } from "hono";
13315
13521
 
13316
13522
  // src/directory/directory-workflow.ts
13317
13523
  import { mkdir as mkdir2, writeFile } from "fs/promises";
13318
13524
  import { join as join5 } from "path";
13319
- import { z as z20 } from "zod";
13525
+ import { z as z21 } from "zod";
13320
13526
 
13321
13527
  // src/directory/location-db.ts
13322
13528
  import { access, readFile } from "fs/promises";
@@ -13477,24 +13683,24 @@ async function resolveDirectoryMarkets(options) {
13477
13683
  }
13478
13684
 
13479
13685
  // src/directory/directory-workflow.ts
13480
- var DirectoryWorkflowOptionsSchema = z20.object({
13481
- query: z20.string().min(1),
13482
- state: z20.string().min(2).default("TN"),
13483
- minPopulation: z20.number().int().min(0).default(1e5),
13484
- populationYear: z20.union(POPULATION_YEARS.map((year) => z20.literal(year))).default(2025),
13485
- maxCities: z20.number().int().min(1).max(100).default(25),
13486
- maxResultsPerCity: z20.number().int().min(1).max(50).default(50),
13487
- concurrency: z20.number().int().min(1).max(5).default(5),
13488
- includeZipGroups: z20.boolean().default(true),
13489
- usZipsCsvPath: z20.string().optional(),
13490
- saveCsv: z20.boolean().default(true),
13491
- gl: z20.string().length(2).default("us"),
13492
- hl: z20.string().length(2).default("en"),
13493
- proxyMode: z20.enum(["location", "configured", "none"]).default(DEFAULT_MAPS_PROXY_MODE),
13494
- proxyZip: z20.string().regex(/^\d{5}$/).optional(),
13495
- debug: z20.boolean().default(false),
13496
- headless: z20.boolean().default(true),
13497
- kernelApiKey: z20.string().optional()
13686
+ var DirectoryWorkflowOptionsSchema = z21.object({
13687
+ query: z21.string().min(1),
13688
+ state: z21.string().min(2).default("TN"),
13689
+ minPopulation: z21.number().int().min(0).default(1e5),
13690
+ populationYear: z21.union(POPULATION_YEARS.map((year) => z21.literal(year))).default(2025),
13691
+ maxCities: z21.number().int().min(1).max(100).default(25),
13692
+ maxResultsPerCity: z21.number().int().min(1).max(50).default(50),
13693
+ concurrency: z21.number().int().min(1).max(5).default(5),
13694
+ includeZipGroups: z21.boolean().default(true),
13695
+ usZipsCsvPath: z21.string().optional(),
13696
+ saveCsv: z21.boolean().default(true),
13697
+ gl: z21.string().length(2).default("us"),
13698
+ hl: z21.string().length(2).default("en"),
13699
+ proxyMode: z21.enum(["location", "configured", "none"]).default(DEFAULT_MAPS_PROXY_MODE),
13700
+ proxyZip: z21.string().regex(/^\d{5}$/).optional(),
13701
+ debug: z21.boolean().default(false),
13702
+ headless: z21.boolean().default(true),
13703
+ kernelApiKey: z21.string().optional()
13498
13704
  });
13499
13705
  function errorMessage(err) {
13500
13706
  return err instanceof Error ? err.message : String(err);
@@ -13715,7 +13921,7 @@ async function runDirectoryWorkflowFromPlan(options, plan) {
13715
13921
  }
13716
13922
 
13717
13923
  // src/api/directory-routes.ts
13718
- var directoryApp = new Hono12();
13924
+ var directoryApp = new Hono13();
13719
13925
  directoryApp.post("/run", createApiKeyAuth(), async (c) => {
13720
13926
  const user = c.get("user");
13721
13927
  const body = await c.req.json().catch(() => ({}));
@@ -13788,35 +13994,35 @@ directoryApp.post("/run", createApiKeyAuth(), async (c) => {
13788
13994
  // src/api/workflow-routes.ts
13789
13995
  import { createHmac as createHmac2 } from "crypto";
13790
13996
  import { readFile as readFile2 } from "fs/promises";
13791
- import { Hono as Hono13 } from "hono";
13792
- import { z as z21 } from "zod";
13793
- var workflowApp = new Hono13();
13794
- var WorkflowInputSchema = z21.record(z21.unknown()).default({});
13795
- var WorkflowIdSchema = z21.string().min(1);
13796
- var CadenceSchema = z21.enum(["daily", "weekly", "monthly"]);
13797
- var ScheduleStatusSchema = z21.enum(["active", "paused"]);
13798
- var RunBodySchema = z21.object({
13997
+ import { Hono as Hono14 } from "hono";
13998
+ import { z as z22 } from "zod";
13999
+ var workflowApp = new Hono14();
14000
+ var WorkflowInputSchema = z22.record(z22.unknown()).default({});
14001
+ var WorkflowIdSchema = z22.string().min(1);
14002
+ var CadenceSchema = z22.enum(["daily", "weekly", "monthly"]);
14003
+ var ScheduleStatusSchema = z22.enum(["active", "paused"]);
14004
+ var RunBodySchema = z22.object({
13799
14005
  workflowId: WorkflowIdSchema,
13800
14006
  input: WorkflowInputSchema,
13801
- webhookUrl: z21.string().url().optional()
14007
+ webhookUrl: z22.string().url().optional()
13802
14008
  });
13803
- var ScheduleCreateSchema = z21.object({
14009
+ var ScheduleCreateSchema = z22.object({
13804
14010
  workflowId: WorkflowIdSchema,
13805
- name: z21.string().min(1).max(120).optional(),
14011
+ name: z22.string().min(1).max(120).optional(),
13806
14012
  input: WorkflowInputSchema,
13807
14013
  cadence: CadenceSchema.default("weekly"),
13808
- timezone: z21.string().min(1).max(64).default("UTC"),
13809
- webhookUrl: z21.string().url().optional(),
13810
- nextRunAt: z21.string().datetime().optional()
14014
+ timezone: z22.string().min(1).max(64).default("UTC"),
14015
+ webhookUrl: z22.string().url().optional(),
14016
+ nextRunAt: z22.string().datetime().optional()
13811
14017
  });
13812
- var SchedulePatchSchema = z21.object({
13813
- name: z21.string().min(1).max(120).optional(),
14018
+ var SchedulePatchSchema = z22.object({
14019
+ name: z22.string().min(1).max(120).optional(),
13814
14020
  status: ScheduleStatusSchema.optional(),
13815
14021
  input: WorkflowInputSchema.optional(),
13816
14022
  cadence: CadenceSchema.optional(),
13817
- timezone: z21.string().min(1).max(64).optional(),
13818
- webhookUrl: z21.string().url().nullable().optional(),
13819
- nextRunAt: z21.string().datetime().nullable().optional()
14023
+ timezone: z22.string().min(1).max(64).optional(),
14024
+ webhookUrl: z22.string().url().nullable().optional(),
14025
+ nextRunAt: z22.string().datetime().nullable().optional()
13820
14026
  });
13821
14027
  function hostedWorkflowOutputDir() {
13822
14028
  return workflowOutputBaseDir(process.env.MCP_SCRAPER_WORKFLOW_OUTPUT_DIR?.trim() || "/tmp/mcp-scraper-workflows");
@@ -14320,7 +14526,7 @@ workflowApp.post("/cron/dispatch", async (c) => {
14320
14526
  });
14321
14527
 
14322
14528
  // src/api/serp-intelligence-routes.ts
14323
- import { Hono as Hono14 } from "hono";
14529
+ import { Hono as Hono15 } from "hono";
14324
14530
 
14325
14531
  // src/serp-intelligence/page-snapshot-extractor.ts
14326
14532
  import { createHash as createHash2 } from "crypto";
@@ -14632,7 +14838,7 @@ async function capturePageSnapshots(targets, options = {}) {
14632
14838
  }
14633
14839
 
14634
14840
  // src/serp-intelligence/schemas.ts
14635
- import { z as z22 } from "zod";
14841
+ import { z as z23 } from "zod";
14636
14842
  var SerpIntelligenceDeviceValues = ["desktop", "mobile"];
14637
14843
  var SerpIntelligenceProxyModeValues = ["location", "configured", "none"];
14638
14844
  var SerpIntelligenceAttemptOutcomeValues = [
@@ -14694,171 +14900,171 @@ function isPublicHttpUrl(value) {
14694
14900
  return false;
14695
14901
  }
14696
14902
  }
14697
- var SerpIntelligencePublicHttpUrlSchema = z22.string().url().refine(isPublicHttpUrl, "url must be a public HTTP or HTTPS URL");
14698
- var SerpIntelligenceCaptureBodySchema = z22.object({
14699
- query: z22.string().trim().min(1, "query is required"),
14700
- location: z22.string().trim().min(1).optional(),
14701
- gl: z22.string().trim().length(2).default("us"),
14702
- hl: z22.string().trim().length(2).default("en"),
14703
- device: z22.enum(SerpIntelligenceDeviceValues).default("desktop"),
14704
- proxyMode: z22.enum(SerpIntelligenceProxyModeValues).default(DEFAULT_PROXY_MODE),
14705
- proxyZip: z22.string().regex(/^\d{5}$/).optional(),
14706
- pages: z22.number().int().min(1).max(2).default(1),
14707
- debug: z22.boolean().default(false),
14708
- includePageSnapshots: z22.boolean().default(false),
14709
- pageSnapshotLimit: z22.number().int().min(0).max(10).default(0)
14903
+ var SerpIntelligencePublicHttpUrlSchema = z23.string().url().refine(isPublicHttpUrl, "url must be a public HTTP or HTTPS URL");
14904
+ var SerpIntelligenceCaptureBodySchema = z23.object({
14905
+ query: z23.string().trim().min(1, "query is required"),
14906
+ location: z23.string().trim().min(1).optional(),
14907
+ gl: z23.string().trim().length(2).default("us"),
14908
+ hl: z23.string().trim().length(2).default("en"),
14909
+ device: z23.enum(SerpIntelligenceDeviceValues).default("desktop"),
14910
+ proxyMode: z23.enum(SerpIntelligenceProxyModeValues).default(DEFAULT_PROXY_MODE),
14911
+ proxyZip: z23.string().regex(/^\d{5}$/).optional(),
14912
+ pages: z23.number().int().min(1).max(2).default(1),
14913
+ debug: z23.boolean().default(false),
14914
+ includePageSnapshots: z23.boolean().default(false),
14915
+ pageSnapshotLimit: z23.number().int().min(0).max(10).default(0)
14710
14916
  }).strict();
14711
- var SerpIntelligencePageSnapshotRequestSchema = z22.object({
14917
+ var SerpIntelligencePageSnapshotRequestSchema = z23.object({
14712
14918
  url: SerpIntelligencePublicHttpUrlSchema,
14713
- sourceKind: z22.enum(SerpPageSnapshotSourceKindValues).default("configured_target"),
14714
- sourcePosition: z22.number().int().min(1).optional()
14919
+ sourceKind: z23.enum(SerpPageSnapshotSourceKindValues).default("configured_target"),
14920
+ sourcePosition: z23.number().int().min(1).optional()
14715
14921
  }).strict();
14716
- var SerpIntelligencePageSnapshotsBodySchema = z22.object({
14717
- urls: z22.array(SerpIntelligencePublicHttpUrlSchema).min(1).max(25),
14718
- targets: z22.array(SerpIntelligencePageSnapshotRequestSchema).min(1).max(25).optional(),
14719
- maxConcurrency: z22.number().int().min(1).max(5).default(2),
14720
- timeoutMs: z22.number().int().min(1e3).max(6e4).default(15e3),
14721
- debug: z22.boolean().default(false)
14922
+ var SerpIntelligencePageSnapshotsBodySchema = z23.object({
14923
+ urls: z23.array(SerpIntelligencePublicHttpUrlSchema).min(1).max(25),
14924
+ targets: z23.array(SerpIntelligencePageSnapshotRequestSchema).min(1).max(25).optional(),
14925
+ maxConcurrency: z23.number().int().min(1).max(5).default(2),
14926
+ timeoutMs: z23.number().int().min(1e3).max(6e4).default(15e3),
14927
+ debug: z23.boolean().default(false)
14722
14928
  }).strict();
14723
- var SerpIntelligenceAICitationSchema = z22.object({
14724
- text: z22.string(),
14725
- href: z22.string()
14929
+ var SerpIntelligenceAICitationSchema = z23.object({
14930
+ text: z23.string(),
14931
+ href: z23.string()
14726
14932
  }).strict();
14727
- var SerpIntelligenceOrganicResultSchema = z22.object({
14728
- position: z22.number().int().min(1),
14729
- title: z22.string(),
14730
- url: z22.string(),
14731
- domain: z22.string(),
14732
- cite: z22.string().nullable(),
14733
- snippet: z22.string().nullable(),
14734
- isRedditStyle: z22.boolean(),
14735
- inlineRating: z22.object({
14736
- value: z22.string(),
14737
- count: z22.string()
14933
+ var SerpIntelligenceOrganicResultSchema = z23.object({
14934
+ position: z23.number().int().min(1),
14935
+ title: z23.string(),
14936
+ url: z23.string(),
14937
+ domain: z23.string(),
14938
+ cite: z23.string().nullable(),
14939
+ snippet: z23.string().nullable(),
14940
+ isRedditStyle: z23.boolean(),
14941
+ inlineRating: z23.object({
14942
+ value: z23.string(),
14943
+ count: z23.string()
14738
14944
  }).strict().nullable()
14739
14945
  }).strict();
14740
- var SerpIntelligenceLocationEvidenceSchema = z22.object({
14741
- status: z22.enum(SerpIntelligenceLocalizationStatusValues),
14742
- expected: z22.object({
14743
- city: z22.string(),
14744
- regionCode: z22.string().nullable(),
14745
- canonicalLocation: z22.string()
14946
+ var SerpIntelligenceLocationEvidenceSchema = z23.object({
14947
+ status: z23.enum(SerpIntelligenceLocalizationStatusValues),
14948
+ expected: z23.object({
14949
+ city: z23.string(),
14950
+ regionCode: z23.string().nullable(),
14951
+ canonicalLocation: z23.string()
14746
14952
  }).strict().nullable(),
14747
- candidates: z22.array(z22.object({
14748
- city: z22.string(),
14749
- regionCode: z22.string(),
14750
- count: z22.number().int().min(0),
14751
- examples: z22.array(z22.string())
14953
+ candidates: z23.array(z23.object({
14954
+ city: z23.string(),
14955
+ regionCode: z23.string(),
14956
+ count: z23.number().int().min(0),
14957
+ examples: z23.array(z23.string())
14752
14958
  }).strict())
14753
14959
  }).strict();
14754
- var SerpIntelligenceHarvestResultSchema = z22.object({
14755
- seed: z22.string(),
14756
- location: z22.string().nullable(),
14757
- extractedAt: z22.string(),
14758
- totalQuestions: z22.number().int().min(0),
14759
- surface: z22.enum(["web", "aim", "unknown"]),
14760
- aiOverview: z22.object({
14761
- detected: z22.boolean(),
14762
- text: z22.string().nullable(),
14763
- citations: z22.array(SerpIntelligenceAICitationSchema),
14764
- expanded: z22.boolean().optional(),
14765
- fullyExpanded: z22.boolean().optional(),
14766
- sections: z22.array(z22.string()).optional()
14960
+ var SerpIntelligenceHarvestResultSchema = z23.object({
14961
+ seed: z23.string(),
14962
+ location: z23.string().nullable(),
14963
+ extractedAt: z23.string(),
14964
+ totalQuestions: z23.number().int().min(0),
14965
+ surface: z23.enum(["web", "aim", "unknown"]),
14966
+ aiOverview: z23.object({
14967
+ detected: z23.boolean(),
14968
+ text: z23.string().nullable(),
14969
+ citations: z23.array(SerpIntelligenceAICitationSchema),
14970
+ expanded: z23.boolean().optional(),
14971
+ fullyExpanded: z23.boolean().optional(),
14972
+ sections: z23.array(z23.string()).optional()
14767
14973
  }).strict(),
14768
- aiMode: z22.object({
14769
- detected: z22.boolean(),
14770
- text: z22.string().nullable(),
14771
- citations: z22.array(SerpIntelligenceAICitationSchema)
14974
+ aiMode: z23.object({
14975
+ detected: z23.boolean(),
14976
+ text: z23.string().nullable(),
14977
+ citations: z23.array(SerpIntelligenceAICitationSchema)
14772
14978
  }).strict(),
14773
- tree: z22.array(z22.unknown()),
14774
- flat: z22.array(z22.unknown()),
14775
- videos: z22.array(z22.unknown()),
14776
- forums: z22.array(z22.unknown()),
14777
- organicResults: z22.array(SerpIntelligenceOrganicResultSchema),
14778
- localPack: z22.array(z22.unknown()),
14779
- entityIds: z22.object({
14780
- entities: z22.array(z22.object({
14781
- name: z22.string(),
14782
- kgId: z22.string().nullable(),
14783
- cid: z22.string().nullable(),
14784
- gcid: z22.string().nullable()
14979
+ tree: z23.array(z23.unknown()),
14980
+ flat: z23.array(z23.unknown()),
14981
+ videos: z23.array(z23.unknown()),
14982
+ forums: z23.array(z23.unknown()),
14983
+ organicResults: z23.array(SerpIntelligenceOrganicResultSchema),
14984
+ localPack: z23.array(z23.unknown()),
14985
+ entityIds: z23.object({
14986
+ entities: z23.array(z23.object({
14987
+ name: z23.string(),
14988
+ kgId: z23.string().nullable(),
14989
+ cid: z23.string().nullable(),
14990
+ gcid: z23.string().nullable()
14785
14991
  }).strict()),
14786
- kgIds: z22.array(z22.string()),
14787
- cids: z22.array(z22.string()),
14788
- gcids: z22.array(z22.string())
14992
+ kgIds: z23.array(z23.string()),
14993
+ cids: z23.array(z23.string()),
14994
+ gcids: z23.array(z23.string())
14789
14995
  }).strict(),
14790
- stats: z22.object({
14791
- seed: z22.string(),
14792
- totalQuestions: z22.number().int().min(0),
14793
- maxDepthReached: z22.number().int().min(0),
14794
- durationMs: z22.number().min(0),
14795
- errorCount: z22.number().int().min(0)
14996
+ stats: z23.object({
14997
+ seed: z23.string(),
14998
+ totalQuestions: z23.number().int().min(0),
14999
+ maxDepthReached: z23.number().int().min(0),
15000
+ durationMs: z23.number().min(0),
15001
+ errorCount: z23.number().int().min(0)
14796
15002
  }).strict(),
14797
- diagnostics: z22.object({
14798
- completionStatus: z22.enum(["paa_found", "no_paa", "serp_only"]),
14799
- problem: z22.null(),
14800
- warnings: z22.array(z22.unknown()).optional(),
14801
- debug: z22.object({
15003
+ diagnostics: z23.object({
15004
+ completionStatus: z23.enum(["paa_found", "no_paa", "serp_only"]),
15005
+ problem: z23.null(),
15006
+ warnings: z23.array(z23.unknown()).optional(),
15007
+ debug: z23.object({
14802
15008
  locationEvidence: SerpIntelligenceLocationEvidenceSchema.optional()
14803
15009
  }).passthrough().optional()
14804
15010
  }).passthrough(),
14805
- whatPeopleSaying: z22.array(z22.unknown())
15011
+ whatPeopleSaying: z23.array(z23.unknown())
14806
15012
  }).strict();
14807
- var SerpIntelligenceCaptureAttemptSchema = z22.object({
14808
- attemptNumber: z22.number().int().min(1),
14809
- outcome: z22.enum(SerpIntelligenceAttemptOutcomeValues),
14810
- startedAt: z22.string().optional(),
14811
- completedAt: z22.string().optional(),
14812
- durationMs: z22.number().min(0).optional(),
14813
- problemCode: z22.string().optional(),
14814
- message: z22.string().optional(),
14815
- kernelSessionId: z22.string().nullable().optional(),
14816
- cleanupSucceeded: z22.boolean().nullable().optional()
15013
+ var SerpIntelligenceCaptureAttemptSchema = z23.object({
15014
+ attemptNumber: z23.number().int().min(1),
15015
+ outcome: z23.enum(SerpIntelligenceAttemptOutcomeValues),
15016
+ startedAt: z23.string().optional(),
15017
+ completedAt: z23.string().optional(),
15018
+ durationMs: z23.number().min(0).optional(),
15019
+ problemCode: z23.string().optional(),
15020
+ message: z23.string().optional(),
15021
+ kernelSessionId: z23.string().nullable().optional(),
15022
+ cleanupSucceeded: z23.boolean().nullable().optional()
14817
15023
  }).strict();
14818
- var SerpPageSnapshotCaptureSchema = z22.object({
15024
+ var SerpPageSnapshotCaptureSchema = z23.object({
14819
15025
  url: SerpIntelligencePublicHttpUrlSchema,
14820
15026
  requestedUrl: SerpIntelligencePublicHttpUrlSchema,
14821
15027
  finalUrl: SerpIntelligencePublicHttpUrlSchema.nullable(),
14822
- sourceKind: z22.enum(SerpPageSnapshotSourceKindValues),
14823
- sourcePosition: z22.number().int().min(1).nullable(),
14824
- status: z22.enum(SerpPageFetchStatusValues),
14825
- fetchedVia: z22.enum(SerpPageFetchedViaValues).nullable(),
14826
- httpStatus: z22.number().int().min(100).max(599).nullable(),
14827
- contentType: z22.string().nullable(),
14828
- title: z22.string().nullable(),
15028
+ sourceKind: z23.enum(SerpPageSnapshotSourceKindValues),
15029
+ sourcePosition: z23.number().int().min(1).nullable(),
15030
+ status: z23.enum(SerpPageFetchStatusValues),
15031
+ fetchedVia: z23.enum(SerpPageFetchedViaValues).nullable(),
15032
+ httpStatus: z23.number().int().min(100).max(599).nullable(),
15033
+ contentType: z23.string().nullable(),
15034
+ title: z23.string().nullable(),
14829
15035
  canonicalUrl: SerpIntelligencePublicHttpUrlSchema.nullable(),
14830
- metaDescription: z22.string().nullable(),
14831
- headings: z22.array(z22.object({
14832
- level: z22.number().int().min(1).max(6),
14833
- text: z22.string()
15036
+ metaDescription: z23.string().nullable(),
15037
+ headings: z23.array(z23.object({
15038
+ level: z23.number().int().min(1).max(6),
15039
+ text: z23.string()
14834
15040
  }).strict()).default([]),
14835
- artifact: z22.object({
14836
- htmlBlobUrl: z22.string().url().nullable(),
14837
- textBlobUrl: z22.string().url().nullable(),
14838
- markdownBlobUrl: z22.string().url().nullable(),
14839
- screenshotBlobUrl: z22.string().url().nullable(),
14840
- contentSha256: z22.string().nullable(),
14841
- capturedAt: z22.string().nullable()
15041
+ artifact: z23.object({
15042
+ htmlBlobUrl: z23.string().url().nullable(),
15043
+ textBlobUrl: z23.string().url().nullable(),
15044
+ markdownBlobUrl: z23.string().url().nullable(),
15045
+ screenshotBlobUrl: z23.string().url().nullable(),
15046
+ contentSha256: z23.string().nullable(),
15047
+ capturedAt: z23.string().nullable()
14842
15048
  }).strict(),
14843
- error: z22.object({
14844
- code: z22.string(),
14845
- message: z22.string()
15049
+ error: z23.object({
15050
+ code: z23.string(),
15051
+ message: z23.string()
14846
15052
  }).strict().nullable()
14847
15053
  }).strict();
14848
- var SerpIntelligenceCaptureResponseSchema = z22.object({
15054
+ var SerpIntelligenceCaptureResponseSchema = z23.object({
14849
15055
  harvestResult: SerpIntelligenceHarvestResultSchema,
14850
- attempts: z22.array(SerpIntelligenceCaptureAttemptSchema),
15056
+ attempts: z23.array(SerpIntelligenceCaptureAttemptSchema),
14851
15057
  locationEvidence: SerpIntelligenceLocationEvidenceSchema.nullable(),
14852
- pageSnapshotArtifacts: z22.array(SerpPageSnapshotCaptureSchema),
14853
- billing: z22.object({
14854
- creditsUsed: z22.number().min(0).optional(),
14855
- requestId: z22.string().optional(),
14856
- jobId: z22.string().optional()
15058
+ pageSnapshotArtifacts: z23.array(SerpPageSnapshotCaptureSchema),
15059
+ billing: z23.object({
15060
+ creditsUsed: z23.number().min(0).optional(),
15061
+ requestId: z23.string().optional(),
15062
+ jobId: z23.string().optional()
14857
15063
  }).strict().optional()
14858
15064
  }).strict();
14859
- var SerpIntelligencePageSnapshotsResponseSchema = z22.object({
14860
- pageSnapshotArtifacts: z22.array(SerpPageSnapshotCaptureSchema),
14861
- attempts: z22.array(SerpIntelligenceCaptureAttemptSchema).default([])
15065
+ var SerpIntelligencePageSnapshotsResponseSchema = z23.object({
15066
+ pageSnapshotArtifacts: z23.array(SerpPageSnapshotCaptureSchema),
15067
+ attempts: z23.array(SerpIntelligenceCaptureAttemptSchema).default([])
14862
15068
  }).strict();
14863
15069
 
14864
15070
  // src/serp-intelligence/serp-capture-service.ts
@@ -15030,7 +15236,7 @@ var SERP_INTELLIGENCE_RATE_LIMIT = 60;
15030
15236
  var SERP_INTELLIGENCE_RATE_WINDOW_SECONDS = 60;
15031
15237
  var POST_CAPTURE_ROUTE_LABEL = "POST /capture";
15032
15238
  var POST_PAGE_SNAPSHOTS_ROUTE_LABEL = "POST /page-snapshots";
15033
- var serpIntelligenceApp = new Hono14();
15239
+ var serpIntelligenceApp = new Hono15();
15034
15240
  serpIntelligenceApp.use("*", createApiKeyAuth());
15035
15241
  function structuredError(input) {
15036
15242
  return {
@@ -15199,7 +15405,7 @@ serpIntelligenceApp.post("/page-snapshots", async (c) => {
15199
15405
  });
15200
15406
 
15201
15407
  // src/mcp/mcp-routes.ts
15202
- import { Hono as Hono15 } from "hono";
15408
+ import { Hono as Hono16 } from "hono";
15203
15409
  import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
15204
15410
 
15205
15411
  // src/mcp/memory-inprocess-executor.ts
@@ -15726,7 +15932,7 @@ async function requireMcpCallerKey(c) {
15726
15932
  if (!user) return mcpAuthError();
15727
15933
  return { key: callerKey, user };
15728
15934
  }
15729
- var mcpApp = new Hono15();
15935
+ var mcpApp = new Hono16();
15730
15936
  mcpApp.all("/", async (c) => {
15731
15937
  try {
15732
15938
  const keyOrError = await requireMcpCallerKey(c);
@@ -15752,7 +15958,7 @@ mcpApp.all("/", async (c) => {
15752
15958
  });
15753
15959
 
15754
15960
  // src/api/browser-agent-routes.ts
15755
- import { Hono as Hono16 } from "hono";
15961
+ import { Hono as Hono17 } from "hono";
15756
15962
 
15757
15963
  // src/api/browser-agent-db.ts
15758
15964
  import { randomUUID as randomUUID2 } from "crypto";
@@ -17143,7 +17349,7 @@ async function loadOpenSession(id, userId) {
17143
17349
  return row;
17144
17350
  }
17145
17351
  function buildBrowserAgentRoutes() {
17146
- const app2 = new Hono16();
17352
+ const app2 = new Hono17();
17147
17353
  app2.use("*", async (c, next) => {
17148
17354
  await migrateBrowserAgent();
17149
17355
  return next();
@@ -17877,9 +18083,9 @@ if (state.key) { refreshSessions(); if (state.current) selectSession(state.curre
17877
18083
 
17878
18084
  // src/api/stripe-routes.ts
17879
18085
  import Stripe from "stripe";
17880
- import { Hono as Hono17 } from "hono";
18086
+ import { Hono as Hono18 } from "hono";
17881
18087
  var stripe = new Stripe(process.env.STRIPE_SECRET_KEY, { apiVersion: "2026-02-25.clover" });
17882
- var stripeApp = new Hono17();
18088
+ var stripeApp = new Hono18();
17883
18089
  stripeApp.post("/webhooks", async (c) => {
17884
18090
  const sig = c.req.header("stripe-signature");
17885
18091
  const body = await c.req.text();
@@ -17983,7 +18189,7 @@ async function resolveUser(customerId, emailFallback) {
17983
18189
  }
17984
18190
 
17985
18191
  // src/api/oauth-routes.ts
17986
- import { Hono as Hono18 } from "hono";
18192
+ import { Hono as Hono19 } from "hono";
17987
18193
  import { getCookie, setCookie } from "hono/cookie";
17988
18194
  import { createHash as createHash3, randomBytes as randomBytes2, randomUUID as randomUUID3 } from "crypto";
17989
18195
  import { importPKCS8, exportJWK, SignJWT } from "jose";
@@ -18152,7 +18358,7 @@ function redirectWithError(redirectUri, state, error) {
18152
18358
  if (state) u.searchParams.set("state", state);
18153
18359
  return new Response(null, { status: 302, headers: { Location: u.toString() } });
18154
18360
  }
18155
- var oauthApp = new Hono18();
18361
+ var oauthApp = new Hono19();
18156
18362
  oauthApp.use("*", async (c, next) => {
18157
18363
  c.header("Access-Control-Allow-Origin", "*");
18158
18364
  c.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
@@ -18406,8 +18612,8 @@ oauthApp.post("/oauth/token", async (c) => {
18406
18612
  });
18407
18613
 
18408
18614
  // src/api/chat-routes.ts
18409
- import { Hono as Hono19 } from "hono";
18410
- var chatApp = new Hono19();
18615
+ import { Hono as Hono20 } from "hono";
18616
+ var chatApp = new Hono20();
18411
18617
  function tokenOk(token) {
18412
18618
  return !!token && token.startsWith("mk_") && token.length > 10;
18413
18619
  }
@@ -19077,8 +19283,8 @@ loadChannels();
19077
19283
  }
19078
19284
 
19079
19285
  // src/api/schedule-routes.ts
19080
- import { Hono as Hono20 } from "hono";
19081
- var scheduleApp = new Hono20();
19286
+ import { Hono as Hono21 } from "hono";
19287
+ var scheduleApp = new Hono21();
19082
19288
  function tokenOk2(token) {
19083
19289
  return !!token && token.startsWith("mk_") && token.length > 10;
19084
19290
  }
@@ -19833,7 +20039,7 @@ var sessionAuth = createMiddleware3(async (c, next) => {
19833
20039
  c.set("sessionUser", { ...refreshed, balance_mc: balanceMc });
19834
20040
  return next();
19835
20041
  });
19836
- var app = new Hono21();
20042
+ var app = new Hono22();
19837
20043
  var STRIPE_API_VERSION = "2026-02-25.clover";
19838
20044
  function requireStripeSecret() {
19839
20045
  const secret2 = process.env.STRIPE_SECRET_KEY?.trim();
@@ -21194,7 +21400,7 @@ app.get("/cron/tick", async (c) => {
21194
21400
  if (!process.env.CRON_SECRET || secret2 !== `Bearer ${process.env.CRON_SECRET}`) {
21195
21401
  return c.json({ error: "Unauthorized" }, 401);
21196
21402
  }
21197
- const { drainQueue } = await import("./worker-7XRZNLKB.js");
21403
+ const { drainQueue } = await import("./worker-YHKUJR5P.js");
21198
21404
  const budget = { maxJobs: 10, deadlineMs: Date.now() + 28e4 };
21199
21405
  const workflowDispatchResult = await dispatchDueWorkflowSchedules(`${new URL(c.req.url).protocol}//${new URL(c.req.url).host}`);
21200
21406
  const [results, sweepResult, reapResult, expiredResult, blobCleanup] = await Promise.all([
@@ -21212,7 +21418,7 @@ app.post("/api/internal/extract-refinalize/:id", async (c) => {
21212
21418
  return c.json({ error: "Unauthorized" }, 401);
21213
21419
  }
21214
21420
  const jobId = c.req.param("id");
21215
- const { getExtractJob: getExtractJob2, completeExtractJob: completeExtractJob2 } = await import("./site-extract-repository-4NVO5KQA.js");
21421
+ const { getExtractJob: getExtractJob2, completeExtractJob: completeExtractJob2 } = await import("./site-extract-repository-THBVEXMP.js");
21216
21422
  const { assembleExtractArtifacts } = await import("./extract-bundle-UKE273TV.js");
21217
21423
  const job = await getExtractJob2(jobId);
21218
21424
  if (!job) return c.json({ error: "job not found" }, 404);
@@ -21220,7 +21426,7 @@ app.post("/api/internal/extract-refinalize/:id", async (c) => {
21220
21426
  await completeExtractJob2(jobId, stored);
21221
21427
  let settlement = "already_settled_or_refunded";
21222
21428
  if (job.billedMc == null && job.userId != null) {
21223
- const { settleExtractJob: settleExtractJob2, countSuccessfulPages: countSuccessfulPages2 } = await import("./site-extract-repository-4NVO5KQA.js");
21429
+ const { settleExtractJob: settleExtractJob2, countSuccessfulPages: countSuccessfulPages2 } = await import("./site-extract-repository-THBVEXMP.js");
21224
21430
  const heldMc = Number(job.options.heldMc ?? 0);
21225
21431
  const successful = await countSuccessfulPages2(jobId);
21226
21432
  const usedMc = Math.min(successful * MC_COSTS.page_scrape, heldMc);
@@ -21247,6 +21453,7 @@ app.route("/reddit", redditApp);
21247
21453
  app.route("/video", videoApp);
21248
21454
  app.route("/maps", mapsApp);
21249
21455
  app.route("/trustpilot", trustpilotApp);
21456
+ app.route("/g2", g2App);
21250
21457
  app.route("/directory", directoryApp);
21251
21458
  app.route("/workflows", workflowApp);
21252
21459
  app.route("/serp-intelligence", serpIntelligenceApp);
@@ -21383,4 +21590,4 @@ app.get("/blog/:slug/", (c) => {
21383
21590
  export {
21384
21591
  app
21385
21592
  };
21386
- //# sourceMappingURL=server-LBEYRKM2.js.map
21593
+ //# sourceMappingURL=server-IKT3QVFB.js.map