mcp-scraper 0.46.0 → 0.47.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 (51) hide show
  1. package/README.md +1 -1
  2. package/dist/bin/api-server.cjs +450 -181
  3. package/dist/bin/api-server.cjs.map +1 -1
  4. package/dist/bin/api-server.js +3 -3
  5. package/dist/bin/mcp-scraper-cli.cjs +1 -1
  6. package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
  7. package/dist/bin/mcp-scraper-cli.js +1 -1
  8. package/dist/bin/mcp-scraper-install.cjs +1 -1
  9. package/dist/bin/mcp-scraper-install.cjs.map +1 -1
  10. package/dist/bin/mcp-scraper-install.js +1 -1
  11. package/dist/bin/mcp-stdio-server.cjs +149 -33
  12. package/dist/bin/mcp-stdio-server.cjs.map +1 -1
  13. package/dist/bin/mcp-stdio-server.js +4 -4
  14. package/dist/bin/paa-harvest.cjs.map +1 -1
  15. package/dist/bin/paa-harvest.js +3 -3
  16. package/dist/{chunk-5X7CJEK3.js → chunk-5S6LYQQO.js} +2 -2
  17. package/dist/chunk-5S6LYQQO.js.map +1 -0
  18. package/dist/{chunk-OVD4E4AP.js → chunk-GV5EGE5M.js} +2 -2
  19. package/dist/chunk-H4NWAF5B.js +7 -0
  20. package/dist/chunk-H4NWAF5B.js.map +1 -0
  21. package/dist/{chunk-T5AFM4G5.js → chunk-IWYYZXBR.js} +2 -2
  22. package/dist/{chunk-RJMOOII7.js → chunk-JH7A4HA7.js} +2 -2
  23. package/dist/{chunk-JFOT5JEL.js → chunk-MW3ET532.js} +2 -2
  24. package/dist/{chunk-WT2UHDSE.js → chunk-TV6KPZ6J.js} +2 -2
  25. package/dist/{chunk-BP2IUIAH.js → chunk-XCGQBGDA.js} +192 -38
  26. package/dist/chunk-XCGQBGDA.js.map +1 -0
  27. package/dist/{db-4ABEYNDM.js → db-W3RPRILW.js} +2 -2
  28. package/dist/{extract-bundle-DYMQRQWG.js → extract-bundle-DXWWQER6.js} +3 -3
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.js +3 -3
  31. package/dist/{location-data-repository-HDNCU4Z4.js → location-data-repository-2FJVMTZ2.js} +3 -3
  32. package/dist/{server-SMEHT3OU.js → server-OHMZJRSB.js} +237 -124
  33. package/dist/server-OHMZJRSB.js.map +1 -0
  34. package/dist/{site-extract-repository-G723PZIL.js → site-extract-repository-UULQAGO4.js} +3 -3
  35. package/dist/{worker-4LZGRHDA.js → worker-3QX7LG62.js} +5 -5
  36. package/package.json +2 -2
  37. package/dist/chunk-5X7CJEK3.js.map +0 -1
  38. package/dist/chunk-BP2IUIAH.js.map +0 -1
  39. package/dist/chunk-TQKQK7OV.js +0 -7
  40. package/dist/chunk-TQKQK7OV.js.map +0 -1
  41. package/dist/server-SMEHT3OU.js.map +0 -1
  42. /package/dist/{chunk-OVD4E4AP.js.map → chunk-GV5EGE5M.js.map} +0 -0
  43. /package/dist/{chunk-T5AFM4G5.js.map → chunk-IWYYZXBR.js.map} +0 -0
  44. /package/dist/{chunk-RJMOOII7.js.map → chunk-JH7A4HA7.js.map} +0 -0
  45. /package/dist/{chunk-JFOT5JEL.js.map → chunk-MW3ET532.js.map} +0 -0
  46. /package/dist/{chunk-WT2UHDSE.js.map → chunk-TV6KPZ6J.js.map} +0 -0
  47. /package/dist/{db-4ABEYNDM.js.map → db-W3RPRILW.js.map} +0 -0
  48. /package/dist/{extract-bundle-DYMQRQWG.js.map → extract-bundle-DXWWQER6.js.map} +0 -0
  49. /package/dist/{location-data-repository-HDNCU4Z4.js.map → location-data-repository-2FJVMTZ2.js.map} +0 -0
  50. /package/dist/{site-extract-repository-G723PZIL.js.map → site-extract-repository-UULQAGO4.js.map} +0 -0
  51. /package/dist/{worker-4LZGRHDA.js.map → worker-3QX7LG62.js.map} +0 -0
@@ -10,14 +10,14 @@ import {
10
10
  importHostedCensusPlacesCsv,
11
11
  importHostedZipGroupsCsv,
12
12
  listActiveHostedLocationDatasets
13
- } from "./chunk-WT2UHDSE.js";
13
+ } from "./chunk-TV6KPZ6J.js";
14
14
  import {
15
15
  classifyHarvestProblem,
16
16
  createHarvestAttemptRecorder,
17
17
  deliverWebhook,
18
18
  harvestProblemResponse,
19
19
  serializeHarvestProblem
20
- } from "./chunk-OVD4E4AP.js";
20
+ } from "./chunk-GV5EGE5M.js";
21
21
  import {
22
22
  AIModeSelectors,
23
23
  AIOverviewSelectors,
@@ -44,10 +44,9 @@ import {
44
44
  resolveKernelProxyId,
45
45
  serpArrivalUrl,
46
46
  withRuntimeUserAgent
47
- } from "./chunk-RJMOOII7.js";
47
+ } from "./chunk-JH7A4HA7.js";
48
48
  import {
49
49
  ApiErrorResponseSchema,
50
- ArtifactTemplateConfigSchema,
51
50
  CommonsClaimPublicationInputSchema,
52
51
  CommonsPreparePublicationInputSchema,
53
52
  CommonsPublishEditorialInputSchema,
@@ -55,15 +54,19 @@ import {
55
54
  CreateArtifactTemplateInputSchema,
56
55
  CreateEditorialReadingRoomInputSchema,
57
56
  CreateScheduledRunViewLinkInputSchema,
57
+ EDITORIAL_READING_ROOM_TEMPLATE_PRESET,
58
+ EditorialArtifactTemplateConfigSchema,
58
59
  EditorialReadingRoomV1InputSchema,
59
60
  GetScheduledRunResponseSchema,
60
61
  HttpMcpToolExecutor,
61
62
  InternalScheduledArtifactRenderRequestSchema,
62
63
  ListScheduledRunsQuerySchema,
63
64
  LocalSourcebookSchemaTypeSchema,
65
+ PERSONAL_AUTHORITY_TEMPLATE_PRESET,
66
+ PersonalAuthorityTemplateConfigSchema,
67
+ PersonalAuthorityV1InputSchema,
64
68
  PublicScheduledRunTokenSchema,
65
69
  RenewEditorialReadingRoomDownloadInputSchema,
66
- SCHEDULED_ARTIFACT_TEMPLATE_PRESET,
67
70
  ScheduledResultsMcpExecutor,
68
71
  UpdateArtifactTemplateInputSchema,
69
72
  WIZPER_LANGUAGES,
@@ -94,7 +97,7 @@ import {
94
97
  resolveDeploymentProfile,
95
98
  resolveLocalSourcebookSchemaType,
96
99
  transcribeMediaUrl
97
- } from "./chunk-BP2IUIAH.js";
100
+ } from "./chunk-XCGQBGDA.js";
98
101
  import {
99
102
  auditImageUrls,
100
103
  auditImages,
@@ -122,7 +125,7 @@ import {
122
125
  recordKernelSession,
123
126
  recordVendorUsage,
124
127
  runWithCostContext
125
- } from "./chunk-T5AFM4G5.js";
128
+ } from "./chunk-IWYYZXBR.js";
126
129
  import {
127
130
  listWorkflowDefinitions,
128
131
  runWorkflow,
@@ -150,7 +153,7 @@ import {
150
153
  } from "./chunk-3ZUBQQPQ.js";
151
154
  import {
152
155
  PACKAGE_VERSION
153
- } from "./chunk-TQKQK7OV.js";
156
+ } from "./chunk-H4NWAF5B.js";
154
157
  import {
155
158
  abandonExtractSettlement,
156
159
  countSuccessfulPages,
@@ -173,7 +176,7 @@ import {
173
176
  setExtractJobTotal,
174
177
  settleExtractJob,
175
178
  terminalExtractJobStatus
176
- } from "./chunk-JFOT5JEL.js";
179
+ } from "./chunk-MW3ET532.js";
177
180
  import {
178
181
  BROWSER_OPEN_MIN_BALANCE_MC,
179
182
  CONCURRENCY_PRICE_ID,
@@ -330,7 +333,7 @@ import {
330
333
  startHarvestAttempt,
331
334
  upsertPageSnapshot,
332
335
  verifyPassword
333
- } from "./chunk-5X7CJEK3.js";
336
+ } from "./chunk-5S6LYQQO.js";
334
337
 
335
338
  // src/blog/registry.ts
336
339
  var posts = [
@@ -2690,38 +2693,38 @@ function renderCard(card) {
2690
2693
  </div>
2691
2694
  </div>`;
2692
2695
  }
2693
- function renderSection(section, tocTitle) {
2694
- const calloutHtml = section.callout ? `
2696
+ function renderSection(section2, tocTitle) {
2697
+ const calloutHtml = section2.callout ? `
2695
2698
  <div class="callout">
2696
- <p class="callout-eyebrow">${section.callout.eyebrow}</p>
2697
- <h3 class="callout-heading">${section.callout.heading}</h3>
2698
- <p class="callout-body">${section.callout.body}</p>
2699
+ <p class="callout-eyebrow">${section2.callout.eyebrow}</p>
2700
+ <h3 class="callout-heading">${section2.callout.heading}</h3>
2701
+ <p class="callout-body">${section2.callout.body}</p>
2699
2702
  </div>` : "";
2700
- const cardsHtml = section.cards.map(renderCard).join("\n ");
2701
- const interactiveHtml = section.interactiveHtml ? `
2702
- <div class="section-interactive">${section.interactiveHtml}</div>` : "";
2703
- return `<section class="post-section" id="${section.id}" aria-label="${tocTitle}">
2703
+ const cardsHtml = section2.cards.map(renderCard).join("\n ");
2704
+ const interactiveHtml = section2.interactiveHtml ? `
2705
+ <div class="section-interactive">${section2.interactiveHtml}</div>` : "";
2706
+ return `<section class="post-section" id="${section2.id}" aria-label="${tocTitle}">
2704
2707
  <div class="section-header">
2705
- <span class="section-num">${section.num}</span>
2706
- <h2 class="section-title">${section.title}${section.titleItalic ? ` <em>${section.titleItalic}</em>` : ""}</h2>
2707
- <p class="section-deck">${section.deck}</p>
2708
+ <span class="section-num">${section2.num}</span>
2709
+ <h2 class="section-title">${section2.title}${section2.titleItalic ? ` <em>${section2.titleItalic}</em>` : ""}</h2>
2710
+ <p class="section-deck">${section2.deck}</p>
2708
2711
  </div>${calloutHtml}
2709
2712
  <div class="card-stack">
2710
2713
  ${cardsHtml}
2711
2714
  </div>${interactiveHtml}
2712
2715
  </section>`;
2713
2716
  }
2714
- function tocItem(section) {
2715
- const label = `${section.title}${section.titleItalic ? " " + section.titleItalic : ""}`;
2716
- const subItems = section.cards.map((card) => `<li>
2717
+ function tocItem(section2) {
2718
+ const label = `${section2.title}${section2.titleItalic ? " " + section2.titleItalic : ""}`;
2719
+ const subItems = section2.cards.map((card) => `<li>
2717
2720
  <a href="#${card.id}" class="toc-sub-link" data-toc="${card.id}">
2718
2721
  <span class="toc-sub-num">${card.num}</span>
2719
2722
  <span class="toc-sub-label">${card.question}</span>
2720
2723
  </a>
2721
2724
  </li>`).join("\n ");
2722
2725
  return `<li>
2723
- <a href="#${section.id}" class="toc-link" data-toc="${section.id}">
2724
- <span class="toc-num">${section.num}</span>
2726
+ <a href="#${section2.id}" class="toc-link" data-toc="${section2.id}">
2727
+ <span class="toc-num">${section2.num}</span>
2725
2728
  <span class="toc-label">${label}</span>
2726
2729
  </a>
2727
2730
  <ul class="toc-sub-list">
@@ -8676,7 +8679,7 @@ var siteExtractFn = inngest.createFunction(
8676
8679
  });
8677
8680
  }) : null;
8678
8681
  const finalized = await step.run("finalize", async () => {
8679
- const { assembleExtractArtifacts } = await import("./extract-bundle-DYMQRQWG.js");
8682
+ const { assembleExtractArtifacts } = await import("./extract-bundle-DXWWQER6.js");
8680
8683
  const current = await getExtractJob(jobId2);
8681
8684
  if (!current) throw new Error("extract job disappeared before finalization");
8682
8685
  const stored = await assembleExtractArtifacts(current, { branding, imageAudit });
@@ -9618,7 +9621,7 @@ async function resolveUsZipsPath(requestedPath) {
9618
9621
  async function loadZipGroups(stateAbbr, requestedPath, warnings, sourceMode) {
9619
9622
  const mode = resolvedLocationDataMode({ zipSource: sourceMode });
9620
9623
  if (mode === "hosted") {
9621
- const { getHostedZipGroups } = await import("./location-data-repository-HDNCU4Z4.js");
9624
+ const { getHostedZipGroups } = await import("./location-data-repository-2FJVMTZ2.js");
9622
9625
  const hosted = await getHostedZipGroups(stateAbbr);
9623
9626
  if (!hosted.dataset) {
9624
9627
  throw new DirectoryLocationError(
@@ -9681,7 +9684,7 @@ async function resolveDirectoryMarkets(options, config = {}) {
9681
9684
  const sourceUrl = censusStateUrl(state.fips);
9682
9685
  const warnings = [];
9683
9686
  if (resolvedLocationDataMode(config) === "hosted") {
9684
- const { queryHostedLocationMarkets } = await import("./location-data-repository-HDNCU4Z4.js");
9687
+ const { queryHostedLocationMarkets } = await import("./location-data-repository-2FJVMTZ2.js");
9685
9688
  const hosted = await queryHostedLocationMarkets({
9686
9689
  state: state.abbr,
9687
9690
  minPopulation: options.minPopulation,
@@ -16071,8 +16074,8 @@ var YouTubeExtractor = class {
16071
16074
  const sections = slr?.contents ?? [];
16072
16075
  const videos = [];
16073
16076
  const channels = [];
16074
- for (const section of sections) {
16075
- const contents = section.itemSectionRenderer?.contents ?? [];
16077
+ for (const section2 of sections) {
16078
+ const contents = section2.itemSectionRenderer?.contents ?? [];
16076
16079
  for (const item of contents) {
16077
16080
  const rec = item;
16078
16081
  if (rec.videoRenderer) {
@@ -27478,10 +27481,10 @@ oauthApp.post("/oauth/authorize", async (c) => {
27478
27481
  return typeof v === "string" ? v : void 0;
27479
27482
  };
27480
27483
  const p = parseAuthParams(get);
27481
- const action = get("action") ?? "";
27484
+ const action2 = get("action") ?? "";
27482
27485
  const valid = await validateAuthRequest(p);
27483
27486
  if (!valid.ok) return c.text(valid.message, valid.status);
27484
- if (action === "login") {
27487
+ if (action2 === "login") {
27485
27488
  const email = (get("email") ?? "").trim().toLowerCase();
27486
27489
  const password = get("password") ?? "";
27487
27490
  const user2 = email ? await withOAuthDatabaseDeadline("login-user", getUserByEmail(email)) : void 0;
@@ -27495,8 +27498,8 @@ oauthApp.post("/oauth/authorize", async (c) => {
27495
27498
  }
27496
27499
  const user = await sessionUser(getCookie(c, "session"));
27497
27500
  if (!user) return c.html(renderLogin(p, "Your session expired. Please sign in again."));
27498
- if (action === "deny") return redirectWithError(p.redirect_uri, p.state, "access_denied");
27499
- if (action !== "approve") return c.text("unsupported action", 400);
27501
+ if (action2 === "deny") return redirectWithError(p.redirect_uri, p.state, "access_denied");
27502
+ if (action2 !== "approve") return c.text("unsupported action", 400);
27500
27503
  const scope = negotiateScope(p.scope, user, p.resource);
27501
27504
  const code = `code_${randomBytes2(32).toString("base64url")}`;
27502
27505
  const expiresAt = new Date(Date.now() + CODE_TTL_SECONDS * 1e3).toISOString();
@@ -28552,12 +28555,12 @@ vaultApp.post("/api/communications/review", async (c) => {
28552
28555
  const token4 = typeof body.token === "string" ? body.token : void 0;
28553
28556
  if (!validToken(token4)) return c.json({ ok: false, error: "missing or malformed Vault App link" }, 401);
28554
28557
  const path5 = stringValue(body.path, 320);
28555
- const action = stringValue(body.action, 24);
28558
+ const action2 = stringValue(body.action, 24);
28556
28559
  const title = typeof body.title === "string" ? stringValue(body.title, 320) : void 0;
28557
28560
  const content = typeof body.content === "string" && body.content.length <= 1e5 ? body.content : void 0;
28558
28561
  const feedback = typeof body.feedback === "string" ? body.feedback.trim().slice(0, 1e4) : void 0;
28559
28562
  const baseRevision = typeof body.baseRevision === "number" && Number.isInteger(body.baseRevision) ? body.baseRevision : void 0;
28560
- const normalizedAction = action === "accept" ? "approve" : action;
28563
+ const normalizedAction = action2 === "accept" ? "approve" : action2;
28561
28564
  if (!path5 || !normalizedAction || !["approve", "deny", "edit"].includes(normalizedAction) || body.title !== void 0 && !title) {
28562
28565
  return c.json({ ok: false, error: "valid path, action, and optional draft fields are required" }, 400);
28563
28566
  }
@@ -30690,30 +30693,30 @@ function renderEditorialReadingRoomV1(input, config, now = /* @__PURE__ */ new D
30690
30693
  startLabel: "Start reading"
30691
30694
  },
30692
30695
  deck: input.dek ?? `Prepared for ${input.generatedFor}.`,
30693
- articles: input.sections.map((section, index) => {
30696
+ articles: input.sections.map((section2, index) => {
30694
30697
  const provenance = [
30695
30698
  "",
30696
30699
  "## Sources",
30697
30700
  "",
30698
- ...section.sourceLabels.map((label) => `- ${label}`),
30699
- ...section.sourceRefs.map((ref) => `- ${scheduledSourceRef(ref)}`)
30701
+ ...section2.sourceLabels.map((label) => `- ${label}`),
30702
+ ...section2.sourceRefs.map((ref) => `- ${scheduledSourceRef(ref)}`)
30700
30703
  ].join("\n");
30701
- const withFiles = index === input.sections.length - 1 && filesMarkdown ? `${section.markdown}
30704
+ const withFiles = index === input.sections.length - 1 && filesMarkdown ? `${section2.markdown}
30702
30705
 
30703
30706
  ${provenance}
30704
30707
 
30705
- ${filesMarkdown}` : `${section.markdown}
30708
+ ${filesMarkdown}` : `${section2.markdown}
30706
30709
 
30707
30710
  ${provenance}`;
30708
30711
  return {
30709
- slug: section.id,
30712
+ slug: section2.id,
30710
30713
  category: "Report",
30711
- kicker: section.summary ?? "Scheduled result",
30714
+ kicker: section2.summary ?? "Scheduled result",
30712
30715
  order: index + 1,
30713
- title: section.title,
30714
- summary: section.summary ?? section.title,
30716
+ title: section2.title,
30717
+ summary: section2.summary ?? section2.title,
30715
30718
  sourceType: "Scheduled result",
30716
- sourceLabel: section.sourceLabels.join(" \xB7 ").slice(0, 500),
30719
+ sourceLabel: section2.sourceLabels.join(" \xB7 ").slice(0, 500),
30717
30720
  markdown: withFiles
30718
30721
  };
30719
30722
  }),
@@ -31295,7 +31298,7 @@ async function prepareCommonsEntity(input, user) {
31295
31298
  presentHeadings: headings,
31296
31299
  recommendedSections: contract.recommendedSections,
31297
31300
  optionalSections: contract.optionalSections,
31298
- missingRecommendedSections: contract.recommendedSections.filter((section) => !presentHeadingLabels.has(section.toLowerCase())),
31301
+ missingRecommendedSections: contract.recommendedSections.filter((section2) => !presentHeadingLabels.has(section2.toLowerCase())),
31299
31302
  rule: "Use the entity profile as a guide, but omit any section or subsection that is not supported by source evidence."
31300
31303
  },
31301
31304
  instructions: [
@@ -31368,8 +31371,8 @@ async function validateCommonsEntity(input, user) {
31368
31371
  headings,
31369
31372
  placeholderSections,
31370
31373
  requiredOmissionRule: "Omit unsupported profile sections; do not publish sections whose only content is that the source lacks evidence.",
31371
- supportedRecommendedSections: contract.recommendedSections.filter((section) => headings.some((heading) => heading.text.toLowerCase() === section.toLowerCase())),
31372
- unsupportedRecommendedSections: contract.recommendedSections.filter((section) => !headings.some((heading) => heading.text.toLowerCase() === section.toLowerCase()))
31374
+ supportedRecommendedSections: contract.recommendedSections.filter((section2) => headings.some((heading) => heading.text.toLowerCase() === section2.toLowerCase())),
31375
+ unsupportedRecommendedSections: contract.recommendedSections.filter((section2) => !headings.some((heading) => heading.text.toLowerCase() === section2.toLowerCase()))
31373
31376
  },
31374
31377
  tagResolutions: resolveCommonsTags(
31375
31378
  uniqueStrings([...input.tags ?? [], ...input.keywords ?? []]).slice(0, 20),
@@ -31894,7 +31897,7 @@ function unsupportedPlaceholderSections(markdown) {
31894
31897
  /insufficient evidence/i,
31895
31898
  /source material does not/i
31896
31899
  ];
31897
- return sections.filter((section) => placeholderPatterns.some((pattern) => pattern.test(section.body)) && wordCount(section.body) <= 160).map((section) => section.heading);
31900
+ return sections.filter((section2) => placeholderPatterns.some((pattern) => pattern.test(section2.body)) && wordCount(section2.body) <= 160).map((section2) => section2.heading);
31898
31901
  }
31899
31902
  function markdownSectionBodies(markdown) {
31900
31903
  const lines = String(markdown || "").split(/\r?\n/);
@@ -32378,18 +32381,18 @@ function normalizeBody(bodyMarkdown, contentSections) {
32378
32381
  const body = String(bodyMarkdown ?? "").trim();
32379
32382
  if (body) return body.slice(0, 5e5);
32380
32383
  const sections = normalizeContentSections(contentSections);
32381
- return sections.map((section) => `## ${section.heading}
32384
+ return sections.map((section2) => `## ${section2.heading}
32382
32385
 
32383
- ${section.body}`).join("\n\n").slice(0, 5e5);
32386
+ ${section2.body}`).join("\n\n").slice(0, 5e5);
32384
32387
  }
32385
32388
  function normalizeContentSections(sections) {
32386
32389
  if (!Array.isArray(sections)) return [];
32387
- return sections.map((section, index) => ({
32388
- id: normalizeSlug(section.id || section.heading),
32389
- heading: requiredText(section.heading, "section.heading", 1, 180),
32390
- body: requiredText(section.body, "section.body", 1, 1e5),
32391
- position: Number.isFinite(section.position) ? Number(section.position) : index + 1,
32392
- citations: normalizeCitations(section.citations)
32390
+ return sections.map((section2, index) => ({
32391
+ id: normalizeSlug(section2.id || section2.heading),
32392
+ heading: requiredText(section2.heading, "section.heading", 1, 180),
32393
+ body: requiredText(section2.body, "section.body", 1, 1e5),
32394
+ position: Number.isFinite(section2.position) ? Number(section2.position) : index + 1,
32395
+ citations: normalizeCitations(section2.citations)
32393
32396
  })).slice(0, 80);
32394
32397
  }
32395
32398
  function normalizeArticleSections(sections) {
@@ -33582,13 +33585,36 @@ async function ensureScheduledRunViewLinksSchema() {
33582
33585
  artifact_id TEXT NOT NULL,
33583
33586
  title TEXT NOT NULL,
33584
33587
  summary TEXT NOT NULL,
33585
- renderer_key TEXT NOT NULL CHECK (renderer_key = 'editorial_reading_room_v1'),
33588
+ renderer_key TEXT NOT NULL CHECK (renderer_key IN ('editorial_reading_room_v1','personal_authority_v1')),
33586
33589
  token_hash TEXT NOT NULL UNIQUE,
33587
33590
  expires_at TEXT NOT NULL,
33588
33591
  revoked_at TEXT,
33589
33592
  created_at TEXT NOT NULL
33590
33593
  )
33591
33594
  `);
33595
+ const schema = await db.execute({
33596
+ sql: `SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'scheduled_run_view_links' LIMIT 1`,
33597
+ args: []
33598
+ });
33599
+ const createSql = String(schema.rows[0]?.sql ?? "");
33600
+ if (createSql.includes("renderer_key = 'editorial_reading_room_v1'")) {
33601
+ await db.batch([
33602
+ `DROP TABLE IF EXISTS scheduled_run_view_links_v2`,
33603
+ `CREATE TABLE scheduled_run_view_links_v2 (
33604
+ share_id TEXT PRIMARY KEY, owner_id TEXT NOT NULL, run_id TEXT NOT NULL,
33605
+ artifact_id TEXT NOT NULL, title TEXT NOT NULL, summary TEXT NOT NULL,
33606
+ renderer_key TEXT NOT NULL CHECK (renderer_key IN ('editorial_reading_room_v1','personal_authority_v1')),
33607
+ token_hash TEXT NOT NULL UNIQUE, expires_at TEXT NOT NULL, revoked_at TEXT,
33608
+ created_at TEXT NOT NULL
33609
+ )`,
33610
+ `INSERT INTO scheduled_run_view_links_v2
33611
+ SELECT share_id, owner_id, run_id, artifact_id, title, summary, renderer_key,
33612
+ token_hash, expires_at, revoked_at, created_at
33613
+ FROM scheduled_run_view_links`,
33614
+ `DROP TABLE scheduled_run_view_links`,
33615
+ `ALTER TABLE scheduled_run_view_links_v2 RENAME TO scheduled_run_view_links`
33616
+ ], "write");
33617
+ }
33592
33618
  await db.execute(`
33593
33619
  CREATE INDEX IF NOT EXISTS scheduled_run_view_links_owner_run
33594
33620
  ON scheduled_run_view_links(owner_id, run_id, created_at DESC)
@@ -33610,7 +33636,7 @@ function mapRow(row) {
33610
33636
  artifactId: String(row.artifact_id),
33611
33637
  title: String(row.title),
33612
33638
  summary: String(row.summary),
33613
- rendererKey: "editorial_reading_room_v1",
33639
+ rendererKey: row.renderer_key === "personal_authority_v1" ? "personal_authority_v1" : "editorial_reading_room_v1",
33614
33640
  tokenHash: String(row.token_hash),
33615
33641
  expiresAt: String(row.expires_at),
33616
33642
  revokedAt: row.revoked_at == null ? null : String(row.revoked_at),
@@ -33686,6 +33712,121 @@ async function revokeScheduledRunViewLink(ownerId, runId, shareId, now = /* @__P
33686
33712
  return result.rowsAffected > 0;
33687
33713
  }
33688
33714
 
33715
+ // src/personal-authority/render.ts
33716
+ import { createHash as createHash16 } from "crypto";
33717
+ function escapeHtml6(value) {
33718
+ return value.replace(/[&<>"']/g, (character) => ({
33719
+ "&": "&amp;",
33720
+ "<": "&lt;",
33721
+ ">": "&gt;",
33722
+ '"': "&quot;",
33723
+ "'": "&#39;"
33724
+ })[character] ?? character);
33725
+ }
33726
+ function safeHref(value) {
33727
+ const trimmed = value.trim();
33728
+ return /^(?:https?:|mailto:|tel:|#|\/)/i.test(trimmed) ? escapeHtml6(trimmed) : "#";
33729
+ }
33730
+ function initials(name) {
33731
+ return name.split(/\s+/).filter(Boolean).slice(0, 2).map((part) => part[0]?.toUpperCase()).join("") || "PA";
33732
+ }
33733
+ function action(action2, secondary = false) {
33734
+ return `<a class="button${secondary ? " button--secondary" : ""}" href="${safeHref(action2.href)}">${escapeHtml6(action2.label)} <span aria-hidden="true">\u2197</span></a>`;
33735
+ }
33736
+ function section(enabled, html) {
33737
+ return enabled ? html : "";
33738
+ }
33739
+ function renderPersonalAuthorityV1(input, config, generatedAt) {
33740
+ const flags = config.featureFlags;
33741
+ const brand = config.brandName || input.name;
33742
+ const generatedAtIso = generatedAt.toISOString();
33743
+ const social = flags.socialLinks && input.socialLinks.length > 0 ? `<nav class="social" aria-label="Professional profiles">${input.socialLinks.map((link) => `<a href="${safeHref(link.href)}">${escapeHtml6(link.label)}</a>`).join("")}</nav>` : "";
33744
+ const navigation = flags.navigation ? `<button class="menu" type="button" aria-expanded="false" aria-controls="nav">Menu</button><nav id="nav" class="nav" aria-label="Primary navigation"><a href="#about">About</a><a href="#services">Work</a><a href="#proof">Proof</a><a href="#contact">Contact</a></nav>` : "";
33745
+ const authority = input.authority;
33746
+ const consultation = input.consultation;
33747
+ const learning = input.learning;
33748
+ const services = input.services;
33749
+ const proof = input.proof;
33750
+ const finalCta = input.finalCta;
33751
+ const html = `<!doctype html>
33752
+ <html lang="en" data-theme="${config.theme}">
33753
+ <head>
33754
+ <meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
33755
+ <meta name="description" content="${escapeHtml6(input.summary)}"><title>${escapeHtml6(input.name)} \u2014 ${escapeHtml6(input.professionalTitle)}</title>
33756
+ <style>
33757
+ :root{--blue:#2f66eb;--blue-soft:#dbe6ff;--ink:#050708;--paper:#f7f8fb;--white:#fff;--gray:#9ca5b5;--line:#27303b;--serif:Georgia,'Times New Roman',serif;--sans:Arial,Helvetica,sans-serif}*{box-sizing:border-box}html{scroll-behavior:smooth}body{margin:0;background:var(--ink);color:var(--white);font-family:var(--sans);line-height:1.55}a{color:inherit}.skip{position:absolute;left:-9999px}.skip:focus{left:16px;top:16px;z-index:9;background:#fff;color:#000;padding:10px}.header{height:88px;display:flex;align-items:center;justify-content:space-between;padding:0 clamp(20px,4vw,72px);border-bottom:1px solid var(--line);position:relative;z-index:3;background:rgba(5,7,8,.96)}.brand{display:flex;align-items:center;gap:12px;text-decoration:none;font-family:var(--serif);font-size:24px}.mark{width:40px;height:40px;border-radius:50%;display:grid;place-items:center;background:var(--blue);font-family:var(--sans);font-weight:700}.nav{display:flex;align-items:center;gap:28px}.nav a{text-decoration:none;color:#c8ced8;font-size:14px}.nav a:hover{color:#fff}.menu{display:none;background:transparent;color:#fff;border:1px solid #5b6471;padding:10px 14px}.hero{display:grid;grid-template-columns:minmax(0,.9fr) minmax(0,1.25fr);min-height:760px;border-bottom:3px solid var(--blue)}.portrait{display:grid;place-items:end center;background:radial-gradient(circle at 50% 38%,#273243 0,#11161d 38%,#060708 70%);overflow:hidden}.portrait-card{width:min(82%,560px);aspect-ratio:4/5;display:grid;place-items:center;align-self:end;border:1px solid #263142;border-bottom:0;background:linear-gradient(145deg,#252d38,#0b0d10 58%);font-family:var(--serif);font-size:clamp(80px,13vw,180px);color:#d9e4ff;text-shadow:0 0 42px rgba(47,102,235,.5)}.hero-copy{padding:clamp(44px,7vw,110px) clamp(24px,6vw,100px);display:flex;flex-direction:column;justify-content:center;background:linear-gradient(135deg,#080a0d,#101318)}h1,h2,h3,p{margin-top:0}.hero h1{font-family:var(--serif);font-size:clamp(58px,8vw,116px);line-height:.92;font-weight:400;color:var(--blue);margin-bottom:24px}.role{font-family:var(--serif);font-size:clamp(28px,3.8vw,52px);line-height:1.05;border-left:5px solid var(--blue);padding-left:22px;max-width:820px}.summary{color:#c6cbd3;font-size:clamp(17px,1.5vw,22px);max-width:760px}.actions{display:flex;gap:12px;flex-wrap:wrap;margin:24px 0}.button{display:inline-flex;align-items:center;justify-content:space-between;gap:28px;min-height:58px;padding:0 26px;background:var(--blue);border:1px solid var(--blue);text-decoration:none;font-weight:700}.button--secondary{background:transparent;border-color:#5c6572}.social{display:flex;gap:10px;flex-wrap:wrap}.social a{border:1px solid #39414d;border-radius:999px;padding:8px 13px;text-decoration:none;color:#d8dce4;font-size:13px}.light{background:var(--paper);color:#111722;padding:clamp(70px,10vw,150px) clamp(20px,6vw,90px)}.light h2,.section h2{font-family:var(--serif);font-size:clamp(42px,6vw,82px);line-height:1.02;font-weight:400;max-width:1080px}.light p{max-width:920px;color:#4e596a;font-size:18px}.section{padding:clamp(70px,9vw,130px) clamp(20px,6vw,90px);border-bottom:1px solid var(--line)}.section-head{max-width:920px;margin-bottom:46px}.eyebrow{text-transform:uppercase;letter-spacing:.18em;font-size:12px;color:#aab2bf}.consult{display:grid;grid-template-columns:1.3fr .7fr;gap:50px;background:linear-gradient(130deg,#060708,#111721)}.accent-card{min-height:360px;border:1px solid #2a3545;background:linear-gradient(145deg,rgba(47,102,235,.22),transparent 55%);display:grid;place-items:center;font-family:var(--serif);font-size:96px;color:var(--blue)}.grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px}.card{border:1px solid #323a46;padding:26px;min-height:220px;background:#0b0e12}.card h3{font-family:var(--serif);font-size:30px}.card p{color:#b9c0ca}.learning{background:#020303}.topic-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1px;background:#29313c;border:1px solid #29313c}.topic{background:#050708;padding:30px}.topic strong{display:block;color:var(--blue);text-transform:uppercase;font-size:11px;letter-spacing:.15em}.topic h3{font-family:var(--serif);font-size:30px;margin:8px 0}.topic p{color:#aeb6c1}.proof{background:linear-gradient(180deg,#0a0d11,#050607)}.quotes{display:flex;gap:14px;overflow:auto;scroll-snap-type:x mandatory;padding-bottom:12px}.quote{min-width:min(420px,86vw);scroll-snap-align:start;border:1px solid #343d49;padding:30px;background:#0c1015}.quote q{font-family:var(--serif);font-size:30px;line-height:1.25}.quote span{display:block;margin-top:24px;color:#aeb5c0;font-size:12px;text-transform:uppercase;letter-spacing:.12em}.cta{text-align:center;border-top:3px solid var(--blue);background:radial-gradient(circle at 50% 0,rgba(47,102,235,.25),transparent 50%)}.cta h2{margin-left:auto;margin-right:auto}.footer{display:grid;grid-template-columns:1fr auto;gap:40px;padding:46px clamp(20px,6vw,90px);color:#abb3bf}.footer strong{color:#fff;font-family:var(--serif);font-size:26px}.generated{font-size:11px;color:#737d8b;margin-top:10px}html[data-theme='slate']{--blue:#7f95b8;--blue-soft:#dfe6ef}html[data-theme='monochrome']{--blue:#fff;--blue-soft:#e7e7e7}.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0)}
33758
+ @media(max-width:760px){.header{height:78px}.menu{display:block}.nav{display:none;position:absolute;left:0;right:0;top:77px;padding:18px 20px;background:#090b0e;border-bottom:1px solid #303844;flex-direction:column;align-items:stretch}.nav.open{display:flex}.hero{grid-template-columns:1fr;min-height:0}.portrait{min-height:390px}.portrait-card{width:72%;max-height:360px}.hero-copy{padding:48px 20px 66px}.hero h1{font-size:64px}.role{font-size:34px}.actions{display:grid}.button{width:100%}.consult{grid-template-columns:1fr}.accent-card{min-height:220px}.grid,.topic-grid{grid-template-columns:1fr}.light,.section{padding:64px 20px}.light h2,.section h2{font-size:46px}.footer{grid-template-columns:1fr}}
33759
+ </style></head>
33760
+ <body><a class="skip" href="#main">Skip to main content</a>
33761
+ <header class="header"><a class="brand" href="#top"><span class="mark">${escapeHtml6(initials(input.name).slice(0, 1))}</span><strong>${escapeHtml6(brand)}</strong></a>${navigation}</header>
33762
+ <main id="main"><section class="hero" id="top"><div class="portrait" aria-label="Portrait placeholder"><div class="portrait-card" aria-hidden="true">${escapeHtml6(initials(input.name))}</div></div><div class="hero-copy"><h1>${escapeHtml6(input.name)}</h1><p class="role">${escapeHtml6(input.professionalTitle)}</p><p class="summary">${escapeHtml6(input.summary)}</p><div class="actions">${action(input.primaryAction)}${input.secondaryAction ? action(input.secondaryAction, true) : ""}</div>${social}</div></section>
33763
+ ${section(flags.authority && Boolean(authority), `<section class="light" id="about"><h2>${escapeHtml6(authority?.heading ?? "")}</h2>${authority?.paragraphs.map((paragraph) => `<p>${escapeHtml6(paragraph)}</p>`).join("") ?? ""}</section>`)}
33764
+ ${section(flags.consultation && Boolean(consultation), `<section class="section consult"><div><p class="eyebrow">${escapeHtml6(consultation?.eyebrow ?? "Start a conversation")}</p><h2>${escapeHtml6(consultation?.heading ?? "")}</h2><p class="summary">${escapeHtml6(consultation?.summary ?? "")}</p>${consultation ? action(consultation.action) : ""}</div><div class="accent-card" aria-label="Image placeholder">${escapeHtml6(initials(input.name))}</div></section>`)}
33765
+ ${section(flags.learning && Boolean(learning), `<section class="section learning"><div class="section-head"><h2>${escapeHtml6(learning?.heading ?? "")}</h2><p class="summary">${escapeHtml6(learning?.summary ?? "")}</p></div><div class="topic-grid">${learning?.topics.map((topic) => `<article class="topic"><strong>${escapeHtml6(topic.title)}</strong><h3>${escapeHtml6(topic.headline)}</h3><p>${escapeHtml6(topic.summary)}</p>${topic.href ? `<a href="${safeHref(topic.href)}">Explore \u2192</a>` : ""}</article>`).join("") ?? ""}</div></section>`)}
33766
+ ${section(flags.services && Boolean(services), `<section class="section" id="services"><div class="section-head"><h2>${escapeHtml6(services?.heading ?? "")}</h2><p class="summary">${escapeHtml6(services?.summary ?? "")}</p></div><div class="grid">${services?.offers.map((offer) => `<article class="card"><h3>${escapeHtml6(offer.title)}</h3><p>${escapeHtml6(offer.description)}</p>${offer.action ? action(offer.action, true) : ""}</article>`).join("") ?? ""}</div></section>`)}
33767
+ ${section(flags.proof && Boolean(proof), `<section class="section proof" id="proof"><div class="section-head"><h2>${escapeHtml6(proof?.heading ?? "")}</h2><p class="summary">${escapeHtml6(proof?.summary ?? "")}</p></div><div class="quotes">${proof?.testimonials.map((item) => `<article class="quote"><q>${escapeHtml6(item.quote)}</q><span>${escapeHtml6(item.person)}${item.role ? ` / ${escapeHtml6(item.role)}` : ""}</span></article>`).join("") ?? ""}</div></section>`)}
33768
+ ${section(flags.finalCta && Boolean(finalCta), `<section class="section cta" id="contact"><p class="eyebrow">${escapeHtml6(finalCta?.eyebrow ?? "Ready when you are")}</p><h2>${escapeHtml6(finalCta?.heading ?? "")}</h2><p class="summary">${escapeHtml6(finalCta?.summary ?? "")}</p>${finalCta ? action(finalCta.action) : ""}</section>`)}
33769
+ </main><footer class="footer"><div><strong>${escapeHtml6(input.name)}</strong><div>${escapeHtml6(input.professionalTitle)}</div>${config.showGeneratedAt ? `<div class="generated">Generated ${escapeHtml6(generatedAtIso)}</div>` : ""}</div><div>${input.location ? `<div>${escapeHtml6(input.location)}</div>` : ""}${input.email ? `<a href="mailto:${escapeHtml6(input.email)}">${escapeHtml6(input.email)}</a>` : ""}${input.phone ? `<div>${escapeHtml6(input.phone)}</div>` : ""}</div></footer>
33770
+ <script>document.querySelector('.menu')?.addEventListener('click',function(){var nav=document.querySelector('.nav');var open=this.getAttribute('aria-expanded')!=='true';this.setAttribute('aria-expanded',String(open));nav?.classList.toggle('open',open)});document.querySelectorAll('.nav a').forEach(function(link){link.addEventListener('click',function(){document.querySelector('.nav')?.classList.remove('open');document.querySelector('.menu')?.setAttribute('aria-expanded','false')})});</script></body></html>`;
33771
+ const bytes = Buffer.byteLength(html, "utf8");
33772
+ return {
33773
+ html,
33774
+ filename: `${input.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "personal-authority"}.html`,
33775
+ bytes,
33776
+ sha256: createHash16("sha256").update(html).digest("hex"),
33777
+ generatedAt: generatedAtIso
33778
+ };
33779
+ }
33780
+
33781
+ // src/scheduled-artifacts/scheduled-artifact-renderer-registry.ts
33782
+ var editorialReadingRoomV1 = {
33783
+ rendererKey: "editorial_reading_room_v1",
33784
+ rendererVersion: 1,
33785
+ async render(rawInput, rawConfig, generatedAt) {
33786
+ const input = EditorialReadingRoomV1InputSchema.parse(rawInput);
33787
+ const config = EditorialArtifactTemplateConfigSchema.parse(rawConfig);
33788
+ const rendered = renderEditorialReadingRoomV1(input, config, generatedAt);
33789
+ if (rendered.bytes > 2e6) {
33790
+ throw new Error("Scheduled artifact HTML must be 2,000,000 bytes or fewer.");
33791
+ }
33792
+ return {
33793
+ html: rendered.html,
33794
+ filename: rendered.filename,
33795
+ title: input.title,
33796
+ bytes: rendered.bytes,
33797
+ sha256: rendered.sha256,
33798
+ generatedAt: rendered.generatedAt
33799
+ };
33800
+ }
33801
+ };
33802
+ var personalAuthorityV1 = {
33803
+ rendererKey: "personal_authority_v1",
33804
+ rendererVersion: 1,
33805
+ async render(rawInput, rawConfig, generatedAt) {
33806
+ const input = PersonalAuthorityV1InputSchema.parse(rawInput);
33807
+ const config = PersonalAuthorityTemplateConfigSchema.parse(rawConfig);
33808
+ const rendered = renderPersonalAuthorityV1(input, config, generatedAt);
33809
+ if (rendered.bytes > 2e6) {
33810
+ throw new Error("Scheduled artifact HTML must be 2,000,000 bytes or fewer.");
33811
+ }
33812
+ return {
33813
+ ...rendered,
33814
+ title: input.name
33815
+ };
33816
+ }
33817
+ };
33818
+ var scheduledArtifactRendererRegistry = Object.freeze({
33819
+ "editorial_reading_room_v1:1": editorialReadingRoomV1,
33820
+ "personal_authority_v1:1": personalAuthorityV1
33821
+ });
33822
+ function getScheduledArtifactRenderer(rendererKey, rendererVersion) {
33823
+ return scheduledArtifactRendererRegistry[`${rendererKey}:${rendererVersion}`] ?? null;
33824
+ }
33825
+ var scheduledArtifactTemplatePresets = [
33826
+ EDITORIAL_READING_ROOM_TEMPLATE_PRESET,
33827
+ PERSONAL_AUTHORITY_TEMPLATE_PRESET
33828
+ ];
33829
+
33689
33830
  // src/api/scheduled-result-routes.ts
33690
33831
  var TemplateParamsSchema = z33.object({ templateId: z33.string().uuid() }).strict();
33691
33832
  var RunParamsSchema = z33.object({ runId: z33.string().min(1).max(200) }).strict();
@@ -33737,7 +33878,7 @@ scheduledResultApp.get("/artifact-templates", async (c) => {
33737
33878
  c.header("Cache-Control", "private, no-store");
33738
33879
  return c.json({
33739
33880
  ...result,
33740
- presets: Array.isArray(result.presets) ? result.presets : [SCHEDULED_ARTIFACT_TEMPLATE_PRESET]
33881
+ presets: Array.isArray(result.presets) ? result.presets : scheduledArtifactTemplatePresets
33741
33882
  });
33742
33883
  });
33743
33884
  scheduledResultApp.post("/artifact-templates", async (c) => {
@@ -33859,7 +34000,7 @@ scheduledResultApp.delete("/schedule-runs/:runId/view-links/:shareId", async (c)
33859
34000
  import { Hono as Hono33 } from "hono";
33860
34001
 
33861
34002
  // src/scheduled-artifacts/scheduled-run-artifact-store.ts
33862
- import { createHash as createHash16 } from "crypto";
34003
+ import { createHash as createHash17 } from "crypto";
33863
34004
  var SCHEDULED_RUN_ARTIFACT_PREFIX = "scheduled-run-artifacts/";
33864
34005
  var SCHEDULED_RUN_ARTIFACT_DOWNLOAD_TTL_MS = 15 * 60 * 1e3;
33865
34006
  var SCHEDULED_RUN_ARTIFACT_MAX_BYTES = 2e6;
@@ -33875,7 +34016,7 @@ function policy3() {
33875
34016
  };
33876
34017
  }
33877
34018
  function runStorageSegment(runId) {
33878
- return /^[a-zA-Z0-9_-]{1,160}$/.test(runId) ? runId : `run-${createHash16("sha256").update(runId).digest("hex").slice(0, 32)}`;
34019
+ return /^[a-zA-Z0-9_-]{1,160}$/.test(runId) ? runId : `run-${createHash17("sha256").update(runId).digest("hex").slice(0, 32)}`;
33879
34020
  }
33880
34021
  async function createScheduledRunArtifact(args) {
33881
34022
  if (args.rendered.bytes > SCHEDULED_RUN_ARTIFACT_MAX_BYTES) {
@@ -33982,7 +34123,7 @@ publicScheduledResultApp.get("/scheduled-run-view-links/:token/content", async (
33982
34123
  import { Hono as Hono34 } from "hono";
33983
34124
 
33984
34125
  // src/api/scheduler-integration-auth.ts
33985
- import { createHash as createHash17, createHmac as createHmac4, timingSafeEqual as timingSafeEqual3 } from "crypto";
34126
+ import { createHash as createHash18, createHmac as createHmac4, timingSafeEqual as timingSafeEqual3 } from "crypto";
33986
34127
 
33987
34128
  // src/api/service-connections.ts
33988
34129
  import { randomUUID as randomUUID18 } from "crypto";
@@ -34280,7 +34421,7 @@ function signingSecret() {
34280
34421
  return secret2;
34281
34422
  }
34282
34423
  function schedulerIntegrationSignature(args) {
34283
- const bodyHash = createHash17("sha256").update(args.body).digest("hex");
34424
+ const bodyHash = createHash18("sha256").update(args.body).digest("hex");
34284
34425
  return createHmac4("sha256", args.secret).update(`${args.method.toUpperCase()}
34285
34426
  ${args.path}
34286
34427
  ${args.timestamp}
@@ -34335,34 +34476,6 @@ async function verifySchedulerIntegrationRequest(request, rawBody) {
34335
34476
  return { requestId };
34336
34477
  }
34337
34478
 
34338
- // src/scheduled-artifacts/scheduled-artifact-renderer-registry.ts
34339
- var editorialReadingRoomV1 = {
34340
- rendererKey: "editorial_reading_room_v1",
34341
- rendererVersion: 1,
34342
- async render(rawInput, rawConfig, generatedAt) {
34343
- const input = EditorialReadingRoomV1InputSchema.parse(rawInput);
34344
- const config = ArtifactTemplateConfigSchema.parse(rawConfig);
34345
- const rendered = renderEditorialReadingRoomV1(input, config, generatedAt);
34346
- if (rendered.bytes > 2e6) {
34347
- throw new Error("Scheduled artifact HTML must be 2,000,000 bytes or fewer.");
34348
- }
34349
- return {
34350
- html: rendered.html,
34351
- filename: rendered.filename,
34352
- title: input.title,
34353
- bytes: rendered.bytes,
34354
- sha256: rendered.sha256,
34355
- generatedAt: rendered.generatedAt
34356
- };
34357
- }
34358
- };
34359
- var scheduledArtifactRendererRegistry = Object.freeze({
34360
- "editorial_reading_room_v1:1": editorialReadingRoomV1
34361
- });
34362
- function getScheduledArtifactRenderer(rendererKey, rendererVersion) {
34363
- return scheduledArtifactRendererRegistry[`${rendererKey}:${rendererVersion}`] ?? null;
34364
- }
34365
-
34366
34479
  // src/api/scheduled-artifact-internal-routes.ts
34367
34480
  var scheduledArtifactInternalApp = new Hono34();
34368
34481
  function errorPayload(errorCode, error, requestId) {
@@ -34564,13 +34677,13 @@ async function reconcileSiteExtractSettlements(limit = 25) {
34564
34677
  }
34565
34678
 
34566
34679
  // src/api/page-diff.ts
34567
- import { createHash as createHash18 } from "crypto";
34680
+ import { createHash as createHash19 } from "crypto";
34568
34681
  import { diffLines } from "diff";
34569
34682
  var MAX_SNAPSHOT_CONTENT_CHARS = 25e4;
34570
34683
  var MAX_DIFF_HUNKS = 200;
34571
34684
  var MAX_DIFF_LINES_PER_RESPONSE = 2e3;
34572
34685
  function sha256Hex(value) {
34573
- return createHash18("sha256").update(value).digest("hex");
34686
+ return createHash19("sha256").update(value).digest("hex");
34574
34687
  }
34575
34688
  function truncateForStorage(value, maxChars = MAX_SNAPSHOT_CONTENT_CHARS) {
34576
34689
  if (value.length <= maxChars) return { value, truncated: false };
@@ -34684,10 +34797,10 @@ async function persistScrapeBody(user, opts) {
34684
34797
  }
34685
34798
 
34686
34799
  // src/api/scrape-image-sink.ts
34687
- import { createHash as createHash19 } from "crypto";
34800
+ import { createHash as createHash20 } from "crypto";
34688
34801
  var MAX_IMAGES_PER_SCRAPE = 25;
34689
34802
  function idempotencyKey2(userId, vault, input) {
34690
- return `scrape-image-${createHash19("sha256").update(`${userId}\0${vault}\0${input.sourceKind}\0${input.sourceUrl}\0${input.imageUrl ?? ""}\0${input.imageBase64 ?? ""}`).digest("hex")}`;
34803
+ return `scrape-image-${createHash20("sha256").update(`${userId}\0${vault}\0${input.sourceKind}\0${input.sourceUrl}\0${input.imageUrl ?? ""}\0${input.imageBase64 ?? ""}`).digest("hex")}`;
34691
34804
  }
34692
34805
  async function persistScrapeImagesToMemory(user, inputs, vault) {
34693
34806
  const selected = inputs.slice(0, MAX_IMAGES_PER_SCRAPE);
@@ -35159,7 +35272,7 @@ function inferredWaybackCapturedAt(content) {
35159
35272
  }
35160
35273
 
35161
35274
  // src/api/connection-memory-import.ts
35162
- import { createHash as createHash20 } from "crypto";
35275
+ import { createHash as createHash21 } from "crypto";
35163
35276
  var CONNECTION_MEMORY_IMPORT_MAX_ARGS_BYTES = 64 * 1024;
35164
35277
  var CONNECTION_MEMORY_IMPORT_MAX_RESULT_BYTES = 1e6;
35165
35278
  var CONNECTION_MEMORY_IMPORT_MAX_STRING_CHARS = 256e3;
@@ -35189,7 +35302,7 @@ function canonicalJson(value) {
35189
35302
  return JSON.stringify(value);
35190
35303
  }
35191
35304
  function sha2562(value) {
35192
- return createHash20("sha256").update(value).digest("hex");
35305
+ return createHash21("sha256").update(value).digest("hex");
35193
35306
  }
35194
35307
  function sensitiveKey(key) {
35195
35308
  const normalized = key.toLowerCase().replace(/[^a-z0-9]/g, "");
@@ -36200,7 +36313,7 @@ async function dbUsage(identity, plan) {
36200
36313
  }
36201
36314
 
36202
36315
  // src/api/nango-control.ts
36203
- import { createHash as createHash22, randomUUID as randomUUID22 } from "crypto";
36316
+ import { createHash as createHash23, randomUUID as randomUUID22 } from "crypto";
36204
36317
 
36205
36318
  // src/api/slack-archive-analysis.ts
36206
36319
  function isRecord2(value) {
@@ -36574,7 +36687,7 @@ async function exportSlackChannelPage(input, dependencies) {
36574
36687
  }
36575
36688
 
36576
36689
  // src/api/main-nango-transport.ts
36577
- import { createHash as createHash21, randomUUID as randomUUID21 } from "crypto";
36690
+ import { createHash as createHash22, randomUUID as randomUUID21 } from "crypto";
36578
36691
  import { Client, StreamableHTTPClientTransport } from "@modelcontextprotocol/client";
36579
36692
 
36580
36693
  // src/api/connected-tool-policy.ts
@@ -36967,7 +37080,7 @@ async function listNangoToolsDirect(identity, connectionId) {
36967
37080
  });
36968
37081
  const readTools = [...policies.values()].filter((policy4) => policy4.classification === "read").map((policy4) => policy4.name);
36969
37082
  const actionTools = [...policies.values()].filter((policy4) => policy4.classification === "action").map((policy4) => policy4.name);
36970
- const revision = createHash21("sha256").update(JSON.stringify(tools.map((tool) => ({ name: tool.name, inputSchema: tool.inputSchema })))).digest("hex");
37083
+ const revision = createHash22("sha256").update(JSON.stringify(tools.map((tool) => ({ name: tool.name, inputSchema: tool.inputSchema })))).digest("hex");
36971
37084
  await updateServiceConnectionTools(connection.id, readTools, actionTools, revision);
36972
37085
  const refreshed = await getOwnedServiceConnection(identity, connection.id);
36973
37086
  return { connection: refreshed ?? { ...connection, readTools, actionTools, toolRevision: revision }, tools };
@@ -36995,7 +37108,7 @@ async function callNangoToolDirect(args) {
36995
37108
  ratePolicyVersion: CONNECTED_USAGE_RATE_POLICY_VERSION
36996
37109
  });
36997
37110
  const requestId = args.requestId?.trim() || randomUUID21();
36998
- const idempotencyKey3 = `main-nango:${createHash21("sha256").update(args.identity.toLowerCase()).update("\0").update(connection.id).update("\0").update(args.tool).update("\0").update(requestId).digest("hex")}`;
37111
+ const idempotencyKey3 = `main-nango:${createHash22("sha256").update(args.identity.toLowerCase()).update("\0").update(connection.id).update("\0").update(args.tool).update("\0").update(requestId).digest("hex")}`;
36999
37112
  const startedAt = /* @__PURE__ */ new Date();
37000
37113
  const started = performance.now();
37001
37114
  let result;
@@ -37020,7 +37133,7 @@ async function callNangoToolDirect(args) {
37020
37133
  toolName: args.tool,
37021
37134
  operationKind: args.operationKind ?? args.classification,
37022
37135
  outcome: providerError ? "error" : "partial",
37023
- requestId: requestId.length <= 200 ? requestId : createHash21("sha256").update(requestId).digest("hex"),
37136
+ requestId: requestId.length <= 200 ? requestId : createHash22("sha256").update(requestId).digest("hex"),
37024
37137
  startedAt: startedAt.toISOString(),
37025
37138
  completedAt: completedAt.toISOString()
37026
37139
  }
@@ -37062,7 +37175,7 @@ async function describeNangoToolDirect(identity, connectionId, toolName) {
37062
37175
  providerContractHash: MAIN_INTEGRATION_CONTRACT_HASH,
37063
37176
  protocolVersion: null,
37064
37177
  schemaSource: "live_tools_list",
37065
- schemaHash: createHash21("sha256").update(JSON.stringify(projected)).digest("hex"),
37178
+ schemaHash: createHash22("sha256").update(JSON.stringify(projected)).digest("hex"),
37066
37179
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
37067
37180
  };
37068
37181
  }
@@ -37786,8 +37899,8 @@ async function setScheduleConnectionActionsEnabled(identity, connectionId, enabl
37786
37899
  return data.connection.actionsEnabled === true;
37787
37900
  }
37788
37901
  async function callScheduleConnectionAction(identity, connectionId, input, tool, idempotencyKey3) {
37789
- const requestId = `main-connected-action:${createHash22("sha256").update(identity).update("\0").update(idempotencyKey3?.trim() || randomUUID22()).digest("hex")}`;
37790
- const requestDigest = createHash22("sha256").update(connectionId).update("\0").update(tool?.trim() ?? "").update("\0").update(canonicalJson2(input)).digest("hex");
37902
+ const requestId = `main-connected-action:${createHash23("sha256").update(identity).update("\0").update(idempotencyKey3?.trim() || randomUUID22()).digest("hex")}`;
37903
+ const requestDigest = createHash23("sha256").update(connectionId).update("\0").update(tool?.trim() ?? "").update("\0").update(canonicalJson2(input)).digest("hex");
37791
37904
  if (mainOwnsIntegrations()) {
37792
37905
  const selectedTool = tool?.trim();
37793
37906
  if (!selectedTool) throw new NangoControlError("An action tool is required.", 400, "invalid_request", false);
@@ -37938,7 +38051,7 @@ function canonicalJson2(value) {
37938
38051
  return JSON.stringify(value);
37939
38052
  }
37940
38053
  function projectedToolSchemaHash(tool) {
37941
- return createHash22("sha256").update(canonicalJson2(tool)).digest("hex");
38054
+ return createHash23("sha256").update(canonicalJson2(tool)).digest("hex");
37942
38055
  }
37943
38056
  async function describeNangoTool(identity, connectionId, tool, fresh) {
37944
38057
  if (mainOwnsIntegrations()) {
@@ -38217,7 +38330,7 @@ async function callMainOwnedExportPage(identity, input) {
38217
38330
  }
38218
38331
 
38219
38332
  // src/api/resend-control.ts
38220
- import { createHash as createHash23 } from "crypto";
38333
+ import { createHash as createHash24 } from "crypto";
38221
38334
  var DEFAULT_CONNECTION_CONTROL_URL = "https://mcp-scraper-scheduler.vercel.app";
38222
38335
  var RESEND_PROVIDER_CONFIG_KEY = "resend";
38223
38336
  var RESEND_LOGO_URL = "https://cdn.resend.com/brand/resend-icon-black.svg";
@@ -38476,7 +38589,7 @@ async function callResendRead(identity, connectionId, tool, args) {
38476
38589
  return isRecord5(data) ? data.result ?? data : data;
38477
38590
  }
38478
38591
  async function callResendAction(identity, connectionId, tool, input, idempotencyKey3) {
38479
- const requestId = `main-resend-action:${createHash23("sha256").update(identity).update("\0").update(idempotencyKey3.trim()).digest("hex")}`;
38592
+ const requestId = `main-resend-action:${createHash24("sha256").update(identity).update("\0").update(idempotencyKey3.trim()).digest("hex")}`;
38480
38593
  const body = await controlRequest2("/api/internal/resend/actions/call", {
38481
38594
  method: "POST",
38482
38595
  headers: { "x-request-id": requestId },
@@ -40013,12 +40126,12 @@ app.get("/schedule-actions", auth3, async (c) => {
40013
40126
  const r = await memoryCall("listScheduledActionsTool", {}, key);
40014
40127
  if (!r.ok || !Array.isArray(r.actions)) return c.json(r);
40015
40128
  try {
40016
- const actions = await Promise.all(r.actions.map(async (action) => {
40017
- const id = typeof action.id === "string" ? action.id : "";
40018
- const executionMode = action.executionMode === "connection_sync" ? "connection_sync" : "agent";
40019
- if (!id) return { ...action, executionMode, connections: [] };
40129
+ const actions = await Promise.all(r.actions.map(async (action2) => {
40130
+ const id = typeof action2.id === "string" ? action2.id : "";
40131
+ const executionMode = action2.executionMode === "connection_sync" ? "connection_sync" : "agent";
40132
+ if (!id) return { ...action2, executionMode, connections: [] };
40020
40133
  const bindings = await getScheduleConnectionBindings(user.email, id);
40021
- return { ...action, executionMode, connections: bindingsForSchedule(bindings, id) };
40134
+ return { ...action2, executionMode, connections: bindingsForSchedule(bindings, id) };
40022
40135
  }));
40023
40136
  return c.json({
40024
40137
  ...r,
@@ -40028,7 +40141,7 @@ app.get("/schedule-actions", auth3, async (c) => {
40028
40141
  console.warn("[schedule-actions] connection bindings unavailable:", err instanceof Error ? err.message : String(err));
40029
40142
  return c.json({
40030
40143
  ...r,
40031
- actions: r.actions.map((action) => ({ ...action, executionMode: action.executionMode === "connection_sync" ? "connection_sync" : "agent", connections: [] })),
40144
+ actions: r.actions.map((action2) => ({ ...action2, executionMode: action2.executionMode === "connection_sync" ? "connection_sync" : "agent", connections: [] })),
40032
40145
  connectionBindingsUnavailable: true
40033
40146
  });
40034
40147
  }
@@ -40111,7 +40224,7 @@ app.put("/schedule-actions/:id/connections", auth3, requireIntegrationsTier, asy
40111
40224
  if (!key) return c.json({ ok: false, error: error ?? "memory unavailable" }, 503);
40112
40225
  const schedules = await memoryCall("listScheduledActionsTool", {}, key);
40113
40226
  if (!schedules.ok || !Array.isArray(schedules.actions)) return c.json(schedules, 502);
40114
- const schedule = schedules.actions.find((action) => action.id === scheduleActionId);
40227
+ const schedule = schedules.actions.find((action2) => action2.id === scheduleActionId);
40115
40228
  if (!schedule) return c.json({ ok: false, error: "scheduled action not found" }, 404);
40116
40229
  if (schedule.executionMode === "connection_sync") {
40117
40230
  const policyError = connectionSyncSelectionError(connections);
@@ -41528,7 +41641,7 @@ app.get("/cron/tick", async (c) => {
41528
41641
  if (!process.env.CRON_SECRET || secret2 !== `Bearer ${process.env.CRON_SECRET}`) {
41529
41642
  return c.json({ error: "Unauthorized" }, 401);
41530
41643
  }
41531
- const { drainQueue } = await import("./worker-4LZGRHDA.js");
41644
+ const { drainQueue } = await import("./worker-3QX7LG62.js");
41532
41645
  const budget = { maxJobs: 10, deadlineMs: Date.now() + 28e4 };
41533
41646
  const workflowDispatchResult = await dispatchDueWorkflowSchedules(`${new URL(c.req.url).protocol}//${new URL(c.req.url).host}`);
41534
41647
  const [results, sweepResult, reapResult, expiredResult, blobCleanup, connectedDataArtifactCleanup, connectedAccountBilling, directoryWorkflowDispatch, directoryWorkflowReconciliation, directoryArtifactCleanup, siteExtractArtifactCleanup, siteExtractRedispatch, siteExtractReconciliation, paaHarvestRedispatch, paaHarvestReconciliation, localSourcebookRedispatch] = await Promise.all([
@@ -41583,8 +41696,8 @@ app.post("/api/internal/extract-refinalize/:id", async (c) => {
41583
41696
  finishExtractJob: finishExtractJob2,
41584
41697
  terminalExtractJobStatus: terminalExtractJobStatus2,
41585
41698
  extractJobLimitInfo: extractJobLimitInfo2
41586
- } = await import("./site-extract-repository-G723PZIL.js");
41587
- const { assembleExtractArtifacts } = await import("./extract-bundle-DYMQRQWG.js");
41699
+ } = await import("./site-extract-repository-UULQAGO4.js");
41700
+ const { assembleExtractArtifacts } = await import("./extract-bundle-DXWWQER6.js");
41588
41701
  const existing = await getExtractJob2(jobId2);
41589
41702
  if (!existing) return c.json({ error: "job not found" }, 404);
41590
41703
  if (existing.status !== "failed") {
@@ -41611,7 +41724,7 @@ app.post("/api/internal/extract-refinalize/:id", async (c) => {
41611
41724
  if (!updated) return c.json({ error: "job state changed during re-finalization" }, 409);
41612
41725
  let settlement = "already_settled_or_refunded";
41613
41726
  if (job.billedMc == null && job.userId != null) {
41614
- const { settleExtractJob: settleExtractJob3, countSuccessfulPages: countSuccessfulPages2 } = await import("./site-extract-repository-G723PZIL.js");
41727
+ const { settleExtractJob: settleExtractJob3, countSuccessfulPages: countSuccessfulPages2 } = await import("./site-extract-repository-UULQAGO4.js");
41615
41728
  const heldMc = Number(job.options.heldMc ?? 0);
41616
41729
  const successful = await countSuccessfulPages2(jobId2);
41617
41730
  const usedMc = Math.min(successful * MC_COSTS.page_scrape, heldMc);
@@ -41795,4 +41908,4 @@ app.get("/blog/:slug/", (c) => {
41795
41908
  export {
41796
41909
  app
41797
41910
  };
41798
- //# sourceMappingURL=server-SMEHT3OU.js.map
41911
+ //# sourceMappingURL=server-OHMZJRSB.js.map