mcp-scraper 0.48.0 → 0.49.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.
@@ -41371,7 +41371,7 @@ var PACKAGE_VERSION;
41371
41371
  var init_version = __esm({
41372
41372
  "src/version.ts"() {
41373
41373
  "use strict";
41374
- PACKAGE_VERSION = "0.48.0";
41374
+ PACKAGE_VERSION = "0.49.0";
41375
41375
  }
41376
41376
  });
41377
41377
 
@@ -41429,6 +41429,8 @@ seam is noted so you can chain them.
41429
41429
  JSON-LD, media, citations, source metadata, related entities, trails, and saved account filters.
41430
41430
  - Read one published entity -> **commons_get_entity**. It returns the Wikidata-style backend fields,
41431
41431
  JSON-LD, source provenance, media, ledger, and the Wikipedia-style page projection.
41432
+ - Read its machine-verifiable governed relationships -> **commons_get_entity_linkset**. It returns the
41433
+ RFC 9264 linkset projection; do not infer claim status from loose See Also labels.
41432
41434
  - List unresolved See Also concepts -> **commons_list_needs_links**. Use it to find concepts that appear
41433
41435
  in public See Also sections but do not yet have a Commons entity ID or /wiki/ slug.
41434
41436
  - Plan a new or edited entity -> **commons_prepare_entity**. This is the Commons equivalent of
@@ -42565,7 +42567,7 @@ var init_contracts = __esm({
42565
42567
  });
42566
42568
 
42567
42569
  // src/mcp/mcp-tool-schemas.ts
42568
- var import_zod42, WEBSITE_URL_OR_DOMAIN_ERROR, WebsiteUrlOrDomainSchema, HarvestPaaInputSchema, ExtractUrlBaseInputSchema, ExtractUrlInputSchema, ExtractUrlLocalInputSchema, DiffPageBaseInputSchema, DiffPageInputSchema, DiffPageLocalInputSchema, MapSiteUrlsInputSchema, MapWaybackSnapshotsInputSchema, ExtractSiteInputSchema, AuditSiteInputSchema, CheckSiteExportInputSchema, ArchiveReadInputSchema, YoutubeHarvestInputSchema, YoutubeTranscribeInputSchema, FacebookPageIntelInputSchema, FacebookAdSearchInputSchema, RedditThreadInputSchema, RedditTrendingInputSchema, VideoFrameAnalysisInputSchema, VideoFrameAnalysisStatusInputSchema, FacebookAdTranscribeInputSchema, FacebookVideoTranscribeInputSchema, GoogleAdsSearchInputSchema, GoogleAdsPageIntelInputSchema, GoogleAdsTranscribeInputSchema, InstagramProfileContentInputSchema, InstagramMediaDownloadInputSchema, MapsPlaceIntelInputSchema, TrustpilotReviewsInputSchema, G2ReviewsInputSchema, ReviewCardSchema, MapsSearchInputSchema, DirectoryWorkflowInputSchema, LocationMarketsInputSchema, CommonsSearchEntitiesInputSchema, CommonsGetEntityInputSchema, CommonsFeaturedImageInputSchema, CommonsMediaInputSchema, CommonsCitationInputSchema, CommonsSourceInputSchema, CommonsRelatedLinkInputSchema, CommonsPrepareEntityInputSchema, CommonsSubmitEntityInputSchema, CommonsValidateEntityInputSchema, CommonsGetEntityLedgerInputSchema, CommonsSaveFilterInputSchema, CommonsListFiltersInputSchema, CommonsListNeedsLinksInputSchema, CommonsGenericOutputSchema, DirectoryWorkflowStatusInputSchema, LocalSourcebookSubmitInputSchema, LocalSourcebookCategorySchema, LocalSourcebookSchemaTypeInputSchema, LocalSourcebookTagCandidateObjectSchema, LocalSourcebookTagDecisionObjectSchema, LocalSourcebookIdentityObjectSchema, GetLocalSourcebookContractInputSchema, ListLocalSourcebookTagsInputSchema, ResolveLocalSourcebookTagsInputSchema, PrepareLocalSourcebookWriteInputSchema, ValidateLocalSourcebookWriteInputSchema, LocalSourcebookCaptureInputSchema, LocalSourcebookSubmissionStatusInputSchema, LocalSourcebookRefreshInputSchema, LocalSourcebookOutputSchema, ArtifactPointerOutputSchema, EditorialReadingRoomSiteSchema, EditorialReadingRoomArticleSchema, EditorialReadingRoomGuideInputSchema, EditorialReadingRoomGuideOutputSchema, CreateEditorialReadingRoomInputSchema, EditorialReadingRoomArtifactSchema, CreateEditorialReadingRoomOutputSchema, RenewEditorialReadingRoomDownloadInputSchema, RenewEditorialReadingRoomDownloadOutputSchema, CommonsPublicationSubdomainSchema, CommonsPreparePublicationInputSchema, CommonsValidatePublicationInputSchema, CommonsClaimPublicationInputSchema, CommonsPublishEditorialInputSchema, CommonsGetPublicationInputSchema, RankTrackerModeSchema, RankTrackerBlueprintInputSchema, NullableString, MapsSearchAttemptOutput, MapsSearchOutputSchema, DirectoryMapsBusinessOutput, DirectoryCsvArtifactOutput, DirectoryWorkflowOutputSchema, LocationDatasetProvenanceOutput, LocationMarketsOutputSchema, RankTrackerToolPlanOutput, RankTrackerTableOutput, RankTrackerCronJobOutput, RankTrackerBlueprintOutputSchema, OrganicResultOutput, AiOverviewOutput, EntityIdsOutput, HarvestPaaOutputSchema, SearchSerpOutputSchema, ExtractUrlOutputSchema, DiffPageOutputSchema, ExtractSiteOutputSchema, AuditSiteOutputSchema, CheckSiteExportOutputSchema, ArchiveEntryOutputSchema, ArchiveReadOutputSchema, MapsPlaceIntelOutputSchema, TrustpilotReviewsOutputSchema, G2ReviewsOutputSchema, CreditsInfoOutputSchema, MapSiteUrlsOutputSchema, WaybackCaptureOutputSchema, MapWaybackSnapshotsOutputSchema, YoutubeHarvestOutputSchema, FacebookAdSearchOutputSchema, VideoFrameAnalysisOutputSchema, VideoFrameAnalysisStatusOutputSchema, RedditThreadOutputSchema, RedditTrendingOutputSchema, FacebookPageIntelOutputSchema, GoogleAdsSearchOutputSchema, GoogleAdsPageIntelOutputSchema, TranscriptSignalOutput, FacebookVideoTranscribeOutputSchema, TranscriptChunkOutput, InstagramBrowserOutput, InstagramPaginationOutput, InstagramProfileContentOutputSchema, InstagramMediaTrackOutput, InstagramDownloadOutput, InstagramMediaDownloadOutputSchema, YoutubeTranscribeOutputSchema, FacebookAdTranscribeOutputSchema, GoogleAdsTranscribeOutputSchema, CaptureSerpSnapshotOutputSchema, CaptureSerpPageSnapshotsOutputSchema, CreditsInfoInputSchema, WorkflowIdSchema2, WorkflowListInputSchema, WorkflowSuggestInputSchema, WorkflowRunInputSchema, WorkflowStepInputSchema, WorkflowStatusInputSchema, WorkflowArtifactReadInputSchema, WorkflowRecipeOutput, WorkflowDefinitionOutput, WorkflowArtifactOutput, WorkflowListOutputSchema, WorkflowSuggestOutputSchema, WorkflowRunOutputSchema, WorkflowStepOutputSchema, WorkflowStatusOutputSchema, WorkflowArtifactReadOutputSchema, SearchSerpInputSchema, CaptureSerpSnapshotInputSchema, ScreenshotInputSchema, CaptureSerpPageSnapshotsInputSchema, ReportArtifactReadInputSchema, ReportArtifactReadOutputSchema, ListServiceConnectionsInputSchema, ListServiceConnectionsOutputSchema, TestServiceConnectionInputSchema, TestServiceConnectionOutputSchema, ReadServiceConnectionInputSchema, ReadServiceConnectionOutputSchema, MetaAdCreativeMediaInputSchema, MetaAdCreativeMediaOutputSchema, ImportServiceConnectionToMemoryInputSchema, ImportServiceConnectionToMemoryOutputSchema, DescribeServiceConnectionToolInputSchema, DescribeServiceConnectionToolOutputSchema, ConnectedDataContinuationSchema, ExportConnectedServiceDataInputSchema, ConnectedDataArtifactSchema, ExportConnectedServiceDataOutputSchema, SearchConsoleTableColumnSchema, SearchConsoleTableFilterSchema, ExportSearchConsoleTableDataInputSchema, ExportSearchConsoleTableDataOutputSchema, RenewConnectedDataExportDownloadInputSchema, RenewConnectedDataExportDownloadOutputSchema, CallServiceConnectionActionInputSchema, CallServiceConnectionActionOutputSchema, SetScheduledActionConnectionsInputSchema, SetScheduledActionConnectionsOutputSchema, SlackSendMessageInputSchema, SlackSendMessageOutputSchema, GmailSendMessageInputSchema, GmailSendMessageOutputSchema, GmailSearchContactsInputSchema, GmailSearchContactsOutputSchema, GoogleCalendarCreateEventInputSchema, GoogleCalendarCreateEventOutputSchema, ZoomCreateMeetingInputSchema, ZoomCreateMeetingOutputSchema;
42570
+ var import_zod42, WEBSITE_URL_OR_DOMAIN_ERROR, WebsiteUrlOrDomainSchema, HarvestPaaInputSchema, ExtractUrlBaseInputSchema, ExtractUrlInputSchema, ExtractUrlLocalInputSchema, DiffPageBaseInputSchema, DiffPageInputSchema, DiffPageLocalInputSchema, MapSiteUrlsInputSchema, MapWaybackSnapshotsInputSchema, ExtractSiteInputSchema, AuditSiteInputSchema, CheckSiteExportInputSchema, ArchiveReadInputSchema, YoutubeHarvestInputSchema, YoutubeTranscribeInputSchema, FacebookPageIntelInputSchema, FacebookAdSearchInputSchema, RedditThreadInputSchema, RedditTrendingInputSchema, VideoFrameAnalysisInputSchema, VideoFrameAnalysisStatusInputSchema, FacebookAdTranscribeInputSchema, FacebookVideoTranscribeInputSchema, GoogleAdsSearchInputSchema, GoogleAdsPageIntelInputSchema, GoogleAdsTranscribeInputSchema, InstagramProfileContentInputSchema, InstagramMediaDownloadInputSchema, MapsPlaceIntelInputSchema, TrustpilotReviewsInputSchema, G2ReviewsInputSchema, ReviewCardSchema, MapsSearchInputSchema, DirectoryWorkflowInputSchema, LocationMarketsInputSchema, CommonsSearchEntitiesInputSchema, CommonsGetEntityInputSchema, CommonsGetEntityLinksetInputSchema, CommonsFeaturedImageInputSchema, CommonsMediaInputSchema, CommonsCitationInputSchema, CommonsSourceInputSchema, CommonsRelatedLinkInputSchema, CommonsClaimInputSchema, CommonsPrepareEntityInputSchema, CommonsSubmitEntityInputSchema, CommonsValidateEntityInputSchema, CommonsGetEntityLedgerInputSchema, CommonsSaveFilterInputSchema, CommonsListFiltersInputSchema, CommonsListNeedsLinksInputSchema, CommonsGenericOutputSchema, DirectoryWorkflowStatusInputSchema, LocalSourcebookSubmitInputSchema, LocalSourcebookCategorySchema, LocalSourcebookSchemaTypeInputSchema, LocalSourcebookTagCandidateObjectSchema, LocalSourcebookTagDecisionObjectSchema, LocalSourcebookIdentityObjectSchema, GetLocalSourcebookContractInputSchema, ListLocalSourcebookTagsInputSchema, ResolveLocalSourcebookTagsInputSchema, PrepareLocalSourcebookWriteInputSchema, ValidateLocalSourcebookWriteInputSchema, LocalSourcebookCaptureInputSchema, LocalSourcebookSubmissionStatusInputSchema, LocalSourcebookRefreshInputSchema, LocalSourcebookOutputSchema, ArtifactPointerOutputSchema, EditorialReadingRoomSiteSchema, EditorialReadingRoomArticleSchema, EditorialReadingRoomGuideInputSchema, EditorialReadingRoomGuideOutputSchema, CreateEditorialReadingRoomInputSchema, EditorialReadingRoomArtifactSchema, CreateEditorialReadingRoomOutputSchema, RenewEditorialReadingRoomDownloadInputSchema, RenewEditorialReadingRoomDownloadOutputSchema, CommonsPublicationSubdomainSchema, CommonsPreparePublicationInputSchema, CommonsValidatePublicationInputSchema, CommonsClaimPublicationInputSchema, CommonsPublishEditorialInputSchema, CommonsGetPublicationInputSchema, RankTrackerModeSchema, RankTrackerBlueprintInputSchema, NullableString, MapsSearchAttemptOutput, MapsSearchOutputSchema, DirectoryMapsBusinessOutput, DirectoryCsvArtifactOutput, DirectoryWorkflowOutputSchema, LocationDatasetProvenanceOutput, LocationMarketsOutputSchema, RankTrackerToolPlanOutput, RankTrackerTableOutput, RankTrackerCronJobOutput, RankTrackerBlueprintOutputSchema, OrganicResultOutput, AiOverviewOutput, EntityIdsOutput, HarvestPaaOutputSchema, SearchSerpOutputSchema, ExtractUrlOutputSchema, DiffPageOutputSchema, ExtractSiteOutputSchema, AuditSiteOutputSchema, CheckSiteExportOutputSchema, ArchiveEntryOutputSchema, ArchiveReadOutputSchema, MapsPlaceIntelOutputSchema, TrustpilotReviewsOutputSchema, G2ReviewsOutputSchema, CreditsInfoOutputSchema, MapSiteUrlsOutputSchema, WaybackCaptureOutputSchema, MapWaybackSnapshotsOutputSchema, YoutubeHarvestOutputSchema, FacebookAdSearchOutputSchema, VideoFrameAnalysisOutputSchema, VideoFrameAnalysisStatusOutputSchema, RedditThreadOutputSchema, RedditTrendingOutputSchema, FacebookPageIntelOutputSchema, GoogleAdsSearchOutputSchema, GoogleAdsPageIntelOutputSchema, TranscriptSignalOutput, FacebookVideoTranscribeOutputSchema, TranscriptChunkOutput, InstagramBrowserOutput, InstagramPaginationOutput, InstagramProfileContentOutputSchema, InstagramMediaTrackOutput, InstagramDownloadOutput, InstagramMediaDownloadOutputSchema, YoutubeTranscribeOutputSchema, FacebookAdTranscribeOutputSchema, GoogleAdsTranscribeOutputSchema, CaptureSerpSnapshotOutputSchema, CaptureSerpPageSnapshotsOutputSchema, CreditsInfoInputSchema, WorkflowIdSchema2, WorkflowListInputSchema, WorkflowSuggestInputSchema, WorkflowRunInputSchema, WorkflowStepInputSchema, WorkflowStatusInputSchema, WorkflowArtifactReadInputSchema, WorkflowRecipeOutput, WorkflowDefinitionOutput, WorkflowArtifactOutput, WorkflowListOutputSchema, WorkflowSuggestOutputSchema, WorkflowRunOutputSchema, WorkflowStepOutputSchema, WorkflowStatusOutputSchema, WorkflowArtifactReadOutputSchema, SearchSerpInputSchema, CaptureSerpSnapshotInputSchema, ScreenshotInputSchema, CaptureSerpPageSnapshotsInputSchema, ReportArtifactReadInputSchema, ReportArtifactReadOutputSchema, ListServiceConnectionsInputSchema, ListServiceConnectionsOutputSchema, TestServiceConnectionInputSchema, TestServiceConnectionOutputSchema, ReadServiceConnectionInputSchema, ReadServiceConnectionOutputSchema, MetaAdCreativeMediaInputSchema, MetaAdCreativeMediaOutputSchema, ImportServiceConnectionToMemoryInputSchema, ImportServiceConnectionToMemoryOutputSchema, DescribeServiceConnectionToolInputSchema, DescribeServiceConnectionToolOutputSchema, ConnectedDataContinuationSchema, ExportConnectedServiceDataInputSchema, ConnectedDataArtifactSchema, ExportConnectedServiceDataOutputSchema, SearchConsoleTableColumnSchema, SearchConsoleTableFilterSchema, ExportSearchConsoleTableDataInputSchema, ExportSearchConsoleTableDataOutputSchema, RenewConnectedDataExportDownloadInputSchema, RenewConnectedDataExportDownloadOutputSchema, CallServiceConnectionActionInputSchema, CallServiceConnectionActionOutputSchema, SetScheduledActionConnectionsInputSchema, SetScheduledActionConnectionsOutputSchema, SlackSendMessageInputSchema, SlackSendMessageOutputSchema, GmailSendMessageInputSchema, GmailSendMessageOutputSchema, GmailSearchContactsInputSchema, GmailSearchContactsOutputSchema, GoogleCalendarCreateEventInputSchema, GoogleCalendarCreateEventOutputSchema, ZoomCreateMeetingInputSchema, ZoomCreateMeetingOutputSchema;
42569
42571
  var init_mcp_tool_schemas = __esm({
42570
42572
  "src/mcp/mcp-tool-schemas.ts"() {
42571
42573
  "use strict";
@@ -42870,6 +42872,9 @@ var init_mcp_tool_schemas = __esm({
42870
42872
  idOrSlug: import_zod42.z.string().trim().min(1).max(180).describe("Transparent Public Wiki entity id such as TPW-Q... or a public /wiki/ slug."),
42871
42873
  includeWikiPage: import_zod42.z.boolean().default(true).describe("Include the Wikipedia-style page projection used by transparent-commons.cc/wiki/.")
42872
42874
  };
42875
+ CommonsGetEntityLinksetInputSchema = {
42876
+ idOrSlug: import_zod42.z.string().trim().min(1).max(180).describe("Transparent Commons TPW-Q entity id or /wiki/ slug whose governed RFC 9264 linkset should be read.")
42877
+ };
42873
42878
  CommonsFeaturedImageInputSchema = import_zod42.z.object({
42874
42879
  url: import_zod42.z.string().url().describe("Required public image URL for a publishable entity. Use extract_url includeFeaturedImage or preserved media when available."),
42875
42880
  alt: import_zod42.z.string().trim().max(500).optional(),
@@ -42922,6 +42927,27 @@ var init_mcp_tool_schemas = __esm({
42922
42927
  imageUrl: import_zod42.z.string().trim().max(2e3).optional().describe("Optional preview image for hover cards when available."),
42923
42928
  needsLink: import_zod42.z.boolean().default(false).describe("Set true when the concept belongs in See Also but no existing Commons entity/page exists yet. The backend exposes these records through commons_list_needs_links.")
42924
42929
  }).strict();
42930
+ CommonsClaimInputSchema = import_zod42.z.object({
42931
+ predicate: import_zod42.z.string().trim().min(1).max(500).describe("Registered link relation such as related, describedby, license, or type; alternatively an absolute HTTPS relation URI from a published vocabulary."),
42932
+ predicateLabel: import_zod42.z.string().trim().max(160).optional().describe("Human-readable label for display and review. It does not replace the machine predicate."),
42933
+ objectEntityId: import_zod42.z.string().trim().regex(/^TPW-Q[A-Za-z0-9._-]+$/).max(80).optional().describe("Existing Transparent Commons entity target. Use exactly one of objectEntityId or objectUrl."),
42934
+ objectUrl: import_zod42.z.string().url().refine((value) => value.startsWith("https://"), "objectUrl must use HTTPS.").optional().describe("External or third-party target. Use exactly one of objectUrl or objectEntityId."),
42935
+ title: import_zod42.z.string().trim().max(500).optional(),
42936
+ mediaType: import_zod42.z.string().trim().max(160).optional().describe("Optional RFC link target media type."),
42937
+ hreflang: import_zod42.z.array(import_zod42.z.string().trim().min(1).max(80)).max(20).optional().describe("Optional repeatable RFC link target language hints."),
42938
+ qualifiers: import_zod42.z.record(import_zod42.z.string().max(120), import_zod42.z.union([import_zod42.z.string(), import_zod42.z.number(), import_zod42.z.boolean(), import_zod42.z.null()])).optional(),
42939
+ references: import_zod42.z.array(CommonsCitationInputSchema).max(50).optional().describe("Evidence supporting the relationship assertion."),
42940
+ rank: import_zod42.z.enum(["preferred", "normal", "deprecated"]).default("normal"),
42941
+ confidence: import_zod42.z.number().min(0).max(1).default(1),
42942
+ confidenceReason: import_zod42.z.string().trim().max(1e3).optional(),
42943
+ disputeState: import_zod42.z.enum(["undisputed", "attributed", "disputed", "contested", "needs_review", "deprecated"]).default("undisputed"),
42944
+ validFrom: import_zod42.z.string().trim().max(80).optional(),
42945
+ validTo: import_zod42.z.string().trim().max(80).optional(),
42946
+ asOf: import_zod42.z.string().trim().max(80).optional(),
42947
+ sourceFamily: import_zod42.z.enum(["first_party", "partner", "independent", "community", "unknown"]).default("unknown")
42948
+ }).strict().refine((claim) => Boolean(claim.objectEntityId) !== Boolean(claim.objectUrl), {
42949
+ message: "Provide exactly one of objectEntityId or objectUrl."
42950
+ });
42925
42951
  CommonsPrepareEntityInputSchema = {
42926
42952
  title: import_zod42.z.string().trim().min(1).max(180).describe("Candidate public page title. Used to derive slug, choose a profile, and search duplicate entities."),
42927
42953
  description: import_zod42.z.string().trim().max(600).optional().describe("Optional candidate summary. Include when known so the prepare pass can route and validate the article shape."),
@@ -42961,6 +42987,7 @@ var init_mcp_tool_schemas = __esm({
42961
42987
  url: import_zod42.z.string().url().optional(),
42962
42988
  description: import_zod42.z.string().trim().max(300).optional()
42963
42989
  }).strict()).max(200).optional().describe("Related concepts, including trails. Existing entities should use entityId."),
42990
+ claims: import_zod42.z.array(CommonsClaimInputSchema).max(300).optional().describe("Governed relationship assertions. Supplying claims replaces the accepted claim set for this entity; omitting claims preserves it. Only approved, active, non-disputed claims project into the RFC 9264 linkset."),
42964
42991
  bodyMarkdown: import_zod42.z.string().max(5e5).optional().describe("Structured encyclopedia body in neutral Markdown, not a raw scrape dump or blog essay. Use H2 for entity-profile sections and H3/H4/H5 for subtopics; every heading appears in the public page menu. Call commons_prepare_entity first for the live entity profile and commons_validate_entity before submit. Profile sections are adaptive: include History, Pricing, Reception, Timeline, Classification, or similar sections only when source evidence supports them; omit unsupported sections instead of adding empty/filler headings. Apply NPOV, verifiability, and no-original-research rules; self-published sources can support only uncontroversial source-owned facts."),
42965
42992
  contentSections: import_zod42.z.array(import_zod42.z.object({
42966
42993
  id: import_zod42.z.string().trim().max(180).optional(),
@@ -46230,6 +46257,19 @@ function registerPaaExtractorMcpTools(server, executor, options = {}) {
46230
46257
  openWorldHint: false
46231
46258
  }
46232
46259
  }, async (input) => executor.commonsGetEntity(input));
46260
+ server.registerTool("commons_get_entity_linkset", {
46261
+ title: "Transparent Commons RFC 9264 Linkset",
46262
+ description: "Read the governed RFC 9264 application/linkset+json projection for one published Transparent Commons entity. The anchor is the canonical /wiki/ page; only approved, active, non-disputed claims are included, while third-party targets remain explicit HTTPS links.",
46263
+ inputSchema: CommonsGetEntityLinksetInputSchema,
46264
+ outputSchema: recordOutputSchema("commons_get_entity_linkset", CommonsGenericOutputSchema),
46265
+ annotations: {
46266
+ title: "Transparent Commons RFC 9264 Linkset",
46267
+ readOnlyHint: true,
46268
+ destructiveHint: false,
46269
+ idempotentHint: true,
46270
+ openWorldHint: false
46271
+ }
46272
+ }, async (input) => executor.commonsGetEntityLinkset(input));
46233
46273
  server.registerTool("commons_list_needs_links", {
46234
46274
  title: "Transparent Commons Needs-Link Backlog",
46235
46275
  description: "List unresolved See Also concepts from published Transparent Commons pages. Use this after search/lookup when an agent needs to grow the graph: each result names a concept that appears in See Also but does not yet have a resolved Commons entityId or /wiki/ slug. This is platform Commons graph data, not personal Memory storage.",
@@ -47299,6 +47339,9 @@ var init_http_mcp_tool_executor = __esm({
47299
47339
  return result;
47300
47340
  }
47301
47341
  }
47342
+ commonsGetEntityLinkset(input) {
47343
+ return this.getJson(`/commons/entities/${encodeURIComponent(input.idOrSlug)}/linkset?envelope=true`);
47344
+ }
47302
47345
  commonsPrepareEntity(input) {
47303
47346
  return this.call("/commons/entities/prepare", input);
47304
47347
  }
@@ -59404,6 +59447,189 @@ var init_editorial_reading_room_routes = __esm({
59404
59447
  }
59405
59448
  });
59406
59449
 
59450
+ // src/api/commons-linksets.ts
59451
+ function normalizeCommonsClaims(input) {
59452
+ if (input === void 0) return void 0;
59453
+ if (!Array.isArray(input)) throw new Error("claims must be an array.");
59454
+ if (input.length > 300) throw new Error("claims must contain no more than 300 assertions.");
59455
+ const seen = /* @__PURE__ */ new Set();
59456
+ return input.map((claim, index) => {
59457
+ const predicate = String(claim.predicate ?? "").trim();
59458
+ if (!isSupportedPredicate(predicate)) {
59459
+ throw new Error(`claims[${index}].predicate must be a supported registered relation or an absolute HTTPS relation URI.`);
59460
+ }
59461
+ const objectEntityId = optionalText(claim.objectEntityId, 80);
59462
+ const objectUrl = optionalHttpsUrl(claim.objectUrl, `claims[${index}].objectUrl`);
59463
+ if ((objectEntityId ? 1 : 0) + (objectUrl ? 1 : 0) !== 1) {
59464
+ throw new Error(`claims[${index}] must provide exactly one of objectEntityId or objectUrl.`);
59465
+ }
59466
+ if (objectEntityId && !/^TPW-Q[A-Za-z0-9._-]+$/.test(objectEntityId)) {
59467
+ throw new Error(`claims[${index}].objectEntityId must be a Transparent Commons TPW-Q identifier.`);
59468
+ }
59469
+ const confidence = claim.confidence ?? 1;
59470
+ if (!Number.isFinite(confidence) || confidence < 0 || confidence > 1) {
59471
+ throw new Error(`claims[${index}].confidence must be between 0 and 1.`);
59472
+ }
59473
+ const key = `${predicate}\0${objectEntityId ?? objectUrl}`;
59474
+ if (seen.has(key)) throw new Error(`claims[${index}] duplicates another predicate and object pair.`);
59475
+ seen.add(key);
59476
+ return {
59477
+ predicate,
59478
+ predicateLabel: optionalText(claim.predicateLabel, 160),
59479
+ objectEntityId,
59480
+ objectUrl,
59481
+ title: optionalText(claim.title, 500),
59482
+ mediaType: optionalText(claim.mediaType, 160),
59483
+ hreflang: normalizeHreflang(claim.hreflang),
59484
+ qualifiers: normalizeScalarRecord(claim.qualifiers),
59485
+ references: normalizeReferences(claim.references),
59486
+ rank: claim.rank ?? "normal",
59487
+ confidence,
59488
+ confidenceReason: optionalText(claim.confidenceReason, 1e3),
59489
+ disputeState: claim.disputeState ?? "undisputed",
59490
+ validFrom: optionalDate(claim.validFrom, `claims[${index}].validFrom`),
59491
+ validTo: optionalDate(claim.validTo, `claims[${index}].validTo`),
59492
+ asOf: optionalDate(claim.asOf, `claims[${index}].asOf`),
59493
+ sourceFamily: claim.sourceFamily ?? "unknown"
59494
+ };
59495
+ });
59496
+ }
59497
+ function claimIsPublic(claim, now = /* @__PURE__ */ new Date()) {
59498
+ if (claim.reviewState !== "approved" || claim.rank === "deprecated") return false;
59499
+ if (!["undisputed", "attributed"].includes(claim.disputeState ?? "undisputed")) return false;
59500
+ const timestamp2 = now.getTime();
59501
+ if (claim.validFrom && Date.parse(claim.validFrom) > timestamp2) return false;
59502
+ if (claim.validTo && Date.parse(claim.validTo) < timestamp2) return false;
59503
+ return true;
59504
+ }
59505
+ function buildCommonsLinkset(entity, claims) {
59506
+ const publicUrl = `${commonsPublicWikiBaseUrl()}/wiki/${encodeURIComponent(entity.slug)}`;
59507
+ const linksetUrl = commonsLinksetUrl(entity.id);
59508
+ const context = { anchor: publicUrl };
59509
+ const publicClaims = claims.filter((claim) => claimIsPublic(claim)).sort((a, b) => a.predicate.localeCompare(b.predicate) || a.href.localeCompare(b.href) || a.id.localeCompare(b.id));
59510
+ for (const claim of publicClaims) {
59511
+ const targets = context[claim.predicate] ?? [];
59512
+ const target = { href: claim.href };
59513
+ if (claim.mediaType) target.type = claim.mediaType;
59514
+ if (claim.hreflang) target.hreflang = claim.hreflang;
59515
+ if (claim.title) target.title = claim.title;
59516
+ targets.push(target);
59517
+ context[claim.predicate] = targets;
59518
+ }
59519
+ const document2 = { linkset: [context] };
59520
+ const etag = `"${(0, import_node_crypto34.createHash)("sha256").update(JSON.stringify(document2)).digest("hex")}"`;
59521
+ return { document: document2, etag, publicUrl, linksetUrl, profile: COMMONS_RELATIONSHIP_PROFILE };
59522
+ }
59523
+ function commonsLinksetDiscoveryHeader(idOrSlug) {
59524
+ const url = commonsLinksetUrl(idOrSlug);
59525
+ return `<${url}>; rel="linkset"; type="${COMMONS_LINKSET_MEDIA_TYPE}"; profile="${COMMONS_RELATIONSHIP_PROFILE}"`;
59526
+ }
59527
+ function commonsLinksetUrl(idOrSlug) {
59528
+ const base = (process.env.APP_URL?.trim() || "https://mcpscraper.dev").replace(/\/+$/, "");
59529
+ return `${base}/commons/entities/${encodeURIComponent(idOrSlug)}/linkset`;
59530
+ }
59531
+ function commonsClaimIdentityKey(claim) {
59532
+ return `${claim.predicate}\0${claim.objectEntityId ?? claim.objectUrl ?? ""}`;
59533
+ }
59534
+ function commonsPublicWikiBaseUrl() {
59535
+ return (process.env.TRANSPARENT_COMMONS_PUBLIC_BASE_URL?.trim() || "https://transparent-commons.cc").replace(/\/+$/, "");
59536
+ }
59537
+ function isSupportedPredicate(value) {
59538
+ if (REGISTERED_RELATIONS.has(value)) return true;
59539
+ try {
59540
+ const url = new URL(value);
59541
+ return url.protocol === "https:" && Boolean(url.hostname);
59542
+ } catch {
59543
+ return false;
59544
+ }
59545
+ }
59546
+ function optionalText(value, max) {
59547
+ const text2 = String(value ?? "").trim();
59548
+ return text2 ? text2.slice(0, max) : void 0;
59549
+ }
59550
+ function optionalHttpsUrl(value, field) {
59551
+ const text2 = optionalText(value, 2e3);
59552
+ if (!text2) return void 0;
59553
+ try {
59554
+ const url = new URL(text2);
59555
+ if (url.protocol !== "https:") throw new Error();
59556
+ url.hash = "";
59557
+ return url.href;
59558
+ } catch {
59559
+ throw new Error(`${field} must be an absolute HTTPS URL.`);
59560
+ }
59561
+ }
59562
+ function optionalDate(value, field) {
59563
+ const text2 = optionalText(value, 80);
59564
+ if (!text2) return void 0;
59565
+ const timestamp2 = Date.parse(text2);
59566
+ if (!Number.isFinite(timestamp2)) throw new Error(`${field} must be an ISO-compatible date.`);
59567
+ return new Date(timestamp2).toISOString();
59568
+ }
59569
+ function normalizeScalarRecord(value) {
59570
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
59571
+ return Object.fromEntries(Object.entries(value).slice(0, 50).map(([key, item]) => [key.slice(0, 120), item]));
59572
+ }
59573
+ function normalizeReferences(value) {
59574
+ if (!Array.isArray(value)) return void 0;
59575
+ return value.slice(0, 50).map((reference) => ({
59576
+ title: String(reference.title ?? "").trim().slice(0, 240),
59577
+ url: optionalHttpsUrl(reference.url, "claim reference URL"),
59578
+ source: optionalText(reference.source, 240),
59579
+ note: optionalText(reference.note, 1e3),
59580
+ accessedAt: optionalDate(reference.accessedAt, "claim reference accessedAt")
59581
+ })).filter((reference) => reference.title);
59582
+ }
59583
+ function normalizeHreflang(value) {
59584
+ if (!Array.isArray(value)) return void 0;
59585
+ const languages = [...new Set(value.map((item) => optionalText(item, 80)).filter((item) => Boolean(item)))];
59586
+ return languages.length ? languages : void 0;
59587
+ }
59588
+ var import_node_crypto34, COMMONS_LINKSET_MEDIA_TYPE, COMMONS_RELATIONSHIP_PROFILE, REGISTERED_RELATIONS;
59589
+ var init_commons_linksets = __esm({
59590
+ "src/api/commons-linksets.ts"() {
59591
+ "use strict";
59592
+ import_node_crypto34 = require("crypto");
59593
+ COMMONS_LINKSET_MEDIA_TYPE = "application/linkset+json";
59594
+ COMMONS_RELATIONSHIP_PROFILE = "https://mcpscraper.dev/commons/profiles/relationships/v1";
59595
+ REGISTERED_RELATIONS = /* @__PURE__ */ new Set([
59596
+ "about",
59597
+ "alternate",
59598
+ "author",
59599
+ "canonical",
59600
+ "cite-as",
59601
+ "collection",
59602
+ "contents",
59603
+ "copyright",
59604
+ "describedby",
59605
+ "describes",
59606
+ "first",
59607
+ "glossary",
59608
+ "help",
59609
+ "icon",
59610
+ "index",
59611
+ "item",
59612
+ "last",
59613
+ "latest-version",
59614
+ "license",
59615
+ "memento",
59616
+ "next",
59617
+ "original",
59618
+ "predecessor-version",
59619
+ "prev",
59620
+ "related",
59621
+ "replies",
59622
+ "service-desc",
59623
+ "service-doc",
59624
+ "successor-version",
59625
+ "terms-of-service",
59626
+ "type",
59627
+ "via",
59628
+ "version-history"
59629
+ ]);
59630
+ }
59631
+ });
59632
+
59407
59633
  // src/api/commons-repository.ts
59408
59634
  async function ensureCommonsSchema() {
59409
59635
  if (schemaReady2) return;
@@ -59453,6 +59679,42 @@ async function ensureCommonsSchema() {
59453
59679
  { sql: `CREATE INDEX IF NOT EXISTS commons_entities_status_updated ON commons_entities(status, updated_at DESC)`, args: [] },
59454
59680
  { sql: `CREATE INDEX IF NOT EXISTS commons_entities_type_updated ON commons_entities(entity_type, updated_at DESC)`, args: [] },
59455
59681
  { sql: `CREATE INDEX IF NOT EXISTS commons_entities_source_domain ON commons_entities(source_json)`, args: [] },
59682
+ {
59683
+ sql: `
59684
+ CREATE TABLE IF NOT EXISTS commons_claims (
59685
+ id TEXT PRIMARY KEY,
59686
+ subject_entity_id TEXT NOT NULL REFERENCES commons_entities(id),
59687
+ predicate TEXT NOT NULL,
59688
+ predicate_label TEXT,
59689
+ object_entity_id TEXT,
59690
+ object_url TEXT,
59691
+ title TEXT,
59692
+ media_type TEXT,
59693
+ hreflang TEXT,
59694
+ qualifiers_json TEXT NOT NULL DEFAULT '{}',
59695
+ references_json TEXT NOT NULL DEFAULT '[]',
59696
+ rank TEXT NOT NULL DEFAULT 'normal',
59697
+ confidence REAL NOT NULL DEFAULT 1,
59698
+ confidence_reason TEXT,
59699
+ dispute_state TEXT NOT NULL DEFAULT 'undisputed',
59700
+ valid_from TEXT,
59701
+ valid_to TEXT,
59702
+ as_of TEXT,
59703
+ source_family TEXT NOT NULL DEFAULT 'unknown',
59704
+ review_state TEXT NOT NULL DEFAULT 'approved',
59705
+ proposal_id TEXT NOT NULL REFERENCES commons_proposals(id),
59706
+ created_by_user_id INTEGER,
59707
+ updated_by_user_id INTEGER,
59708
+ created_at TEXT NOT NULL,
59709
+ updated_at TEXT NOT NULL,
59710
+ CHECK ((object_entity_id IS NOT NULL) != (object_url IS NOT NULL)),
59711
+ UNIQUE(subject_entity_id, predicate, object_entity_id, object_url)
59712
+ )
59713
+ `,
59714
+ args: []
59715
+ },
59716
+ { sql: `CREATE INDEX IF NOT EXISTS commons_claims_subject_predicate ON commons_claims(subject_entity_id, predicate)`, args: [] },
59717
+ { sql: `CREATE INDEX IF NOT EXISTS commons_claims_object_entity ON commons_claims(object_entity_id)`, args: [] },
59456
59718
  {
59457
59719
  sql: `
59458
59720
  CREATE TABLE IF NOT EXISTS commons_proposals (
@@ -59613,8 +59875,15 @@ async function searchCommonsEntities(filters = {}, userId) {
59613
59875
  args.push(jsonLikeValue(keyword));
59614
59876
  }
59615
59877
  if (mergedFilters.relatedEntityId) {
59616
- clauses.push("related_entities_json LIKE ?");
59617
- args.push(jsonLikeValue(mergedFilters.relatedEntityId));
59878
+ clauses.push(`(
59879
+ related_entities_json LIKE ?
59880
+ OR EXISTS (
59881
+ SELECT 1 FROM commons_claims
59882
+ WHERE commons_claims.subject_entity_id = commons_entities.id
59883
+ AND commons_claims.object_entity_id = ?
59884
+ )
59885
+ )`);
59886
+ args.push(jsonLikeValue(mergedFilters.relatedEntityId), mergedFilters.relatedEntityId);
59618
59887
  }
59619
59888
  if (mergedFilters.trailId) {
59620
59889
  clauses.push("related_entities_json LIKE ?");
@@ -59636,8 +59905,16 @@ async function searchCommonsEntities(filters = {}, userId) {
59636
59905
  }
59637
59906
  const terms = tokenize(mergedFilters.query);
59638
59907
  for (const term of terms) {
59639
- clauses.push("search_text LIKE ?");
59640
- args.push(`%${escapeLike(term)}%`);
59908
+ clauses.push(`(
59909
+ search_text LIKE ?
59910
+ OR EXISTS (
59911
+ SELECT 1 FROM commons_claims
59912
+ WHERE commons_claims.subject_entity_id = commons_entities.id
59913
+ AND (commons_claims.predicate LIKE ? OR commons_claims.predicate_label LIKE ? OR commons_claims.title LIKE ? OR commons_claims.object_url LIKE ?)
59914
+ )
59915
+ )`);
59916
+ const pattern = `%${escapeLike(term)}%`;
59917
+ args.push(pattern, pattern, pattern, pattern, pattern);
59641
59918
  }
59642
59919
  args.push(limit, offset);
59643
59920
  const result = await getDb().execute({
@@ -59659,9 +59936,9 @@ async function searchCommonsEntities(filters = {}, userId) {
59659
59936
  }
59660
59937
  async function prepareCommonsEntity(input, user) {
59661
59938
  await ensureCommonsSchema();
59662
- const title = optionalText(input.title, 180) ?? "";
59939
+ const title = optionalText2(input.title, 180) ?? "";
59663
59940
  const slug2 = normalizeSlug(input.slug || title);
59664
- const schemaOrgType = optionalText(input.schemaOrgType, 80);
59941
+ const schemaOrgType = optionalText2(input.schemaOrgType, 80);
59665
59942
  const contract = commonsEntityProfileFor(input.entityType, schemaOrgType);
59666
59943
  const entityType = contract.entityType;
59667
59944
  const bodyMarkdown = safeCandidateBody(input.bodyMarkdown, input.contentSections);
@@ -59719,8 +59996,8 @@ async function validateCommonsEntity(input, user) {
59719
59996
  await ensureCommonsSchema();
59720
59997
  const errors = [];
59721
59998
  const warnings = [];
59722
- const title = optionalText(input.title, 180);
59723
- const description = optionalText(input.description, 600);
59999
+ const title = optionalText2(input.title, 180);
60000
+ const description = optionalText2(input.description, 600);
59724
60001
  const slug2 = normalizeSlug(input.slug || title || "");
59725
60002
  const contract = commonsEntityProfileFor(input.entityType, input.seo?.schemaOrgType);
59726
60003
  const source = normalizeSource(input.source);
@@ -59735,6 +60012,11 @@ async function validateCommonsEntity(input, user) {
59735
60012
  maxCandidates: 8
59736
60013
  });
59737
60014
  const existing = slug2 || input.entityId ? await findEntityBySlugOrIdAnyStatus(slug2, input.entityId) : null;
60015
+ try {
60016
+ normalizeCommonsClaims(input.claims);
60017
+ } catch (error) {
60018
+ errors.push(error instanceof Error ? error.message : "Claims are invalid.");
60019
+ }
59738
60020
  if (!title || title.length < 3) errors.push("title must be at least 3 characters.");
59739
60021
  if (!description || description.length < 8) errors.push("description must be at least 8 characters.");
59740
60022
  if (!slug2) errors.push("A Commons entity needs a URL slug.");
@@ -59824,9 +60106,10 @@ async function submitCommonsEntity(input, user) {
59824
60106
  };
59825
60107
  }
59826
60108
  const existing = await findEntityBySlugOrIdAnyStatus(normalized.slug, normalized.entityId);
60109
+ const existingClaims = existing && normalized.claims !== void 0 ? await getCommonsClaimsByEntityId(existing.id) : [];
59827
60110
  const safety = evaluatePublishSafety(normalized, existing);
59828
60111
  const shouldApply = safety.safe && normalized.reviewPolicy !== "always_review";
59829
- const proposalId = `commons-proposal-${(0, import_node_crypto34.randomUUID)()}`;
60112
+ const proposalId = `commons-proposal-${(0, import_node_crypto35.randomUUID)()}`;
59830
60113
  const now = (/* @__PURE__ */ new Date()).toISOString();
59831
60114
  const entityId = existing?.id ?? normalized.entityId ?? allocateEntityId();
59832
60115
  const proposalStatus = shouldApply ? "accepted" : "pending_review";
@@ -59868,6 +60151,10 @@ async function submitCommonsEntity(input, user) {
59868
60151
  ];
59869
60152
  if (nextEntity) {
59870
60153
  batch.push(entityUpsertStatement(nextEntity, existing));
60154
+ if (normalized.claims !== void 0) {
60155
+ batch.push({ sql: "DELETE FROM commons_claims WHERE subject_entity_id = ?", args: [nextEntity.id] });
60156
+ batch.push(...claimInsertStatements(normalized.claims, existingClaims, nextEntity.id, proposalId, Number(user.id), now));
60157
+ }
59871
60158
  batch.push(...commonsIndexStatements(nextEntity, now));
59872
60159
  batch.push({
59873
60160
  sql: `
@@ -59877,17 +60164,26 @@ async function submitCommonsEntity(input, user) {
59877
60164
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
59878
60165
  `,
59879
60166
  args: [
59880
- `commons-ledger-${(0, import_node_crypto34.randomUUID)()}`,
60167
+ `commons-ledger-${(0, import_node_crypto35.randomUUID)()}`,
59881
60168
  nextEntity.id,
59882
60169
  proposalId,
59883
60170
  user.id,
59884
60171
  actorLabel(input, user),
59885
60172
  normalized.actorChannel,
59886
60173
  existing ? "entity_updated" : "entity_created",
59887
- JSON.stringify(changedFieldPaths(existing, nextEntity)),
60174
+ JSON.stringify([
60175
+ ...changedFieldPaths(existing, nextEntity),
60176
+ ...normalized.claims !== void 0 ? ["claims"] : []
60177
+ ]),
59888
60178
  normalized.changeSummary || (existing ? "Updated Commons entity." : "Created Commons entity."),
59889
- existing ? JSON.stringify(entityLedgerSnapshot(existing)) : null,
59890
- JSON.stringify(entityLedgerSnapshot(nextEntity)),
60179
+ existing ? JSON.stringify({
60180
+ ...entityLedgerSnapshot(existing),
60181
+ ...normalized.claims !== void 0 ? { claims: existingClaims } : {}
60182
+ }) : null,
60183
+ JSON.stringify({
60184
+ ...entityLedgerSnapshot(nextEntity),
60185
+ ...normalized.claims !== void 0 ? { claims: normalized.claims } : {}
60186
+ }),
59891
60187
  now
59892
60188
  ]
59893
60189
  });
@@ -59938,17 +60234,41 @@ async function getCommonsEntityLedger(idOrSlug) {
59938
60234
  ledger: result.rows.map((row) => rowToLedgerEntry(row))
59939
60235
  };
59940
60236
  }
60237
+ async function listCommonsClaims(idOrSlug) {
60238
+ await ensureCommonsSchema();
60239
+ const entity = await getCommonsEntity(idOrSlug);
60240
+ if (!entity) return null;
60241
+ return { entity, claims: await getCommonsClaimsByEntityId(entity.id) };
60242
+ }
60243
+ async function getCommonsEntityLinkset(idOrSlug) {
60244
+ const result = await listCommonsClaims(idOrSlug);
60245
+ if (!result) return null;
60246
+ const targetIds = [...new Set(result.claims.map((claim) => claim.objectEntityId).filter((id) => Boolean(id)))];
60247
+ const targetSlugs = /* @__PURE__ */ new Map();
60248
+ if (targetIds.length) {
60249
+ const targets = await getDb().execute({
60250
+ sql: `SELECT id, slug FROM commons_entities WHERE status = 'published' AND id IN (${targetIds.map(() => "?").join(", ")})`,
60251
+ args: targetIds
60252
+ });
60253
+ for (const row of targets.rows) targetSlugs.set(String(row.id), String(row.slug));
60254
+ }
60255
+ const resolved = result.claims.map((claim) => {
60256
+ const href = claim.objectUrl ?? (claim.objectEntityId && targetSlugs.has(claim.objectEntityId) ? publicUrlForSlug(targetSlugs.get(claim.objectEntityId)) : null);
60257
+ return href ? { ...claim, href } : null;
60258
+ }).filter((claim) => claim !== null);
60259
+ return { entity: result.entity, claims: result.claims, ...buildCommonsLinkset(result.entity, resolved) };
60260
+ }
59941
60261
  async function saveCommonsFilter(input, user) {
59942
60262
  await ensureCommonsSchema();
59943
60263
  const now = (/* @__PURE__ */ new Date()).toISOString();
59944
60264
  const name = requiredText(input.name, "name", 2, 80);
59945
- const description = optionalText(input.description, 500);
60265
+ const description = optionalText2(input.description, 500);
59946
60266
  const filter = sanitizeSearchFilters(input.filter);
59947
60267
  const existing = await getDb().execute({
59948
60268
  sql: "SELECT id FROM commons_saved_filters WHERE user_id = ? AND name = ? LIMIT 1",
59949
60269
  args: [user.id, name]
59950
60270
  });
59951
- const id = existing.rows[0]?.id != null ? String(existing.rows[0].id) : `commons-filter-${(0, import_node_crypto34.randomUUID)()}`;
60271
+ const id = existing.rows[0]?.id != null ? String(existing.rows[0].id) : `commons-filter-${(0, import_node_crypto35.randomUUID)()}`;
59952
60272
  await getDb().execute({
59953
60273
  sql: `
59954
60274
  INSERT INTO commons_saved_filters (id, user_id, name, description, filter_json, created_at, updated_at)
@@ -60075,9 +60395,9 @@ function commonsDatabaseReport() {
60075
60395
  conflictBehavior: "Existing entity edits require baseRevision. Otherwise the proposal is pending_review.",
60076
60396
  billing: { validationCredits: 0, createCredits: LISTING_WRITE_RATE_POLICY.create.credits, editCredits: LISTING_WRITE_RATE_POLICY.edit.credits }
60077
60397
  },
60078
- searchCorpus: ["title", "disambiguationName", "description", "tags", "keywords", "relatedEntities", "bodyMarkdown", "sections", "media", "source metadata", "jsonLd"],
60398
+ searchCorpus: ["title", "disambiguationName", "description", "tags", "keywords", "relatedEntities", "relationship claims", "bodyMarkdown", "sections", "media", "source metadata", "jsonLd"],
60079
60399
  indexing: commonsIndexingPolicy(),
60080
- tables: ["commons_entities", "commons_proposals", "commons_ledger", "commons_saved_filters", "commons_index_documents"]
60400
+ tables: ["commons_entities", "commons_claims", "commons_proposals", "commons_ledger", "commons_saved_filters", "commons_index_documents"]
60081
60401
  };
60082
60402
  }
60083
60403
  function entityToWikiPage(entity) {
@@ -60097,6 +60417,13 @@ function entityToWikiPage(entity) {
60097
60417
  media: entity.media,
60098
60418
  sections: entity.articleSections,
60099
60419
  metadata: {
60420
+ linksetUrl: commonsLinksetUrl(entity.id),
60421
+ linksetDiscovery: {
60422
+ rel: "linkset",
60423
+ type: COMMONS_LINKSET_MEDIA_TYPE,
60424
+ profile: COMMONS_RELATIONSHIP_PROFILE,
60425
+ href: commonsLinksetUrl(entity.id)
60426
+ },
60100
60427
  entityType: friendlyEntityType(entity.entityType),
60101
60428
  disambiguationName: entity.disambiguationName,
60102
60429
  keywords: entity.keywords,
@@ -60253,7 +60580,7 @@ async function commonsTagVocabulary() {
60253
60580
  ...parseJson3(record.tags_json, []),
60254
60581
  ...parseJson3(record.keywords_json, [])
60255
60582
  ]) {
60256
- const cleaned = optionalText(tag, 120);
60583
+ const cleaned = optionalText2(tag, 120);
60257
60584
  if (!cleaned) continue;
60258
60585
  counts.set(cleaned, (counts.get(cleaned) ?? 0) + 1);
60259
60586
  }
@@ -60263,7 +60590,7 @@ async function commonsTagVocabulary() {
60263
60590
  function resolveCommonsTags(candidates, vocabulary) {
60264
60591
  const vocabularyByKey = new Map(vocabulary.map((entry) => [entry.tag.toLowerCase(), entry]));
60265
60592
  return candidates.map((candidate) => {
60266
- const cleaned = optionalText(candidate, 120) ?? "";
60593
+ const cleaned = optionalText2(candidate, 120) ?? "";
60267
60594
  const key = cleaned.toLowerCase();
60268
60595
  const exact = vocabularyByKey.get(key);
60269
60596
  if (!cleaned || cleaned.length < 2) {
@@ -60360,12 +60687,13 @@ function normalizeSubmitInput(input) {
60360
60687
  slug: slug2,
60361
60688
  entityId: normalizeEntityId(input.entityId),
60362
60689
  entityType: normalizeEntityType(input.entityType),
60363
- disambiguationName: optionalText(input.disambiguationName, 240) ?? void 0,
60690
+ disambiguationName: optionalText2(input.disambiguationName, 240) ?? void 0,
60364
60691
  featuredImage: normalizeFeaturedImage(input.featuredImage),
60365
60692
  source: normalizeSource(input.source),
60366
60693
  tags: uniqueStrings(input.tags ?? []).slice(0, 24),
60367
60694
  keywords: uniqueStrings(input.keywords ?? []).slice(0, 50),
60368
60695
  relatedEntities: normalizeRelatedEntities(input.relatedEntities),
60696
+ claims: normalizeClaimsForRepository(input.claims),
60369
60697
  bodyMarkdown: normalizeBody(input.bodyMarkdown, input.contentSections),
60370
60698
  contentSections: normalizeContentSections(input.contentSections),
60371
60699
  articleSections: normalizeArticleSections(input.articleSections),
@@ -60374,11 +60702,18 @@ function normalizeSubmitInput(input) {
60374
60702
  seo: normalizeSeo(input.seo),
60375
60703
  actorChannel: input.actorChannel ?? "mcp",
60376
60704
  actorLabel: input.actorLabel ?? "",
60377
- changeSummary: optionalText(input.changeSummary, 500) ?? "",
60705
+ changeSummary: optionalText2(input.changeSummary, 500) ?? "",
60378
60706
  reviewPolicy: input.reviewPolicy ?? "auto_publish_if_safe",
60379
60707
  baseRevision: input.baseRevision
60380
60708
  };
60381
60709
  }
60710
+ function normalizeClaimsForRepository(input) {
60711
+ try {
60712
+ return normalizeCommonsClaims(input);
60713
+ } catch (error) {
60714
+ throw new CommonsRepositoryError("invalid_claims", error instanceof Error ? error.message : "Claims are invalid.");
60715
+ }
60716
+ }
60382
60717
  function evaluatePublishSafety(input, existing) {
60383
60718
  if (!input.featuredImage?.url) return { safe: false, reason: "A featured image is required before a Commons entity can publish." };
60384
60719
  if (!input.bodyMarkdown.trim() && !input.source.originalUrl && !input.source.resolvedUrl) {
@@ -60524,6 +60859,84 @@ function entityStorageValues(entity) {
60524
60859
  entity.revision
60525
60860
  ];
60526
60861
  }
60862
+ function claimInsertStatements(claims, existingClaims, subjectEntityId, proposalId, userId, now) {
60863
+ const existingByIdentity = new Map(existingClaims.map((claim) => [commonsClaimIdentityKey(claim), claim]));
60864
+ return claims.map((claim) => {
60865
+ const existing = existingByIdentity.get(commonsClaimIdentityKey(claim));
60866
+ return {
60867
+ sql: `
60868
+ INSERT INTO commons_claims (
60869
+ id, subject_entity_id, predicate, predicate_label, object_entity_id, object_url,
60870
+ title, media_type, hreflang, qualifiers_json, references_json, rank, confidence,
60871
+ confidence_reason, dispute_state, valid_from, valid_to, as_of, source_family,
60872
+ review_state, proposal_id, created_by_user_id, updated_by_user_id, created_at, updated_at
60873
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'approved', ?, ?, ?, ?, ?)
60874
+ `,
60875
+ args: [
60876
+ existing?.id ?? allocateClaimId(),
60877
+ subjectEntityId,
60878
+ claim.predicate,
60879
+ claim.predicateLabel ?? null,
60880
+ claim.objectEntityId ?? null,
60881
+ claim.objectUrl ?? null,
60882
+ claim.title ?? null,
60883
+ claim.mediaType ?? null,
60884
+ claim.hreflang ? JSON.stringify(claim.hreflang) : null,
60885
+ JSON.stringify(claim.qualifiers ?? {}),
60886
+ JSON.stringify(claim.references ?? []),
60887
+ claim.rank ?? "normal",
60888
+ claim.confidence ?? 1,
60889
+ claim.confidenceReason ?? null,
60890
+ claim.disputeState ?? "undisputed",
60891
+ claim.validFrom ?? null,
60892
+ claim.validTo ?? null,
60893
+ claim.asOf ?? null,
60894
+ claim.sourceFamily ?? "unknown",
60895
+ proposalId,
60896
+ existing?.createdByUserId ?? userId,
60897
+ userId,
60898
+ existing?.createdAt ?? now,
60899
+ now
60900
+ ]
60901
+ };
60902
+ });
60903
+ }
60904
+ async function getCommonsClaimsByEntityId(entityId) {
60905
+ const result = await getDb().execute({
60906
+ sql: "SELECT * FROM commons_claims WHERE subject_entity_id = ? ORDER BY predicate ASC, object_url ASC, object_entity_id ASC, id ASC",
60907
+ args: [entityId]
60908
+ });
60909
+ return result.rows.map((row) => rowToClaim(row));
60910
+ }
60911
+ function rowToClaim(row) {
60912
+ return {
60913
+ id: String(row.id),
60914
+ subjectEntityId: String(row.subject_entity_id),
60915
+ predicate: String(row.predicate),
60916
+ predicateLabel: row.predicate_label == null ? void 0 : String(row.predicate_label),
60917
+ objectEntityId: row.object_entity_id == null ? void 0 : String(row.object_entity_id),
60918
+ objectUrl: row.object_url == null ? void 0 : String(row.object_url),
60919
+ title: row.title == null ? void 0 : String(row.title),
60920
+ mediaType: row.media_type == null ? void 0 : String(row.media_type),
60921
+ hreflang: row.hreflang == null ? void 0 : parseJson3(row.hreflang, []),
60922
+ qualifiers: parseJson3(row.qualifiers_json, {}),
60923
+ references: parseJson3(row.references_json, []),
60924
+ rank: String(row.rank),
60925
+ confidence: Number(row.confidence),
60926
+ confidenceReason: row.confidence_reason == null ? void 0 : String(row.confidence_reason),
60927
+ disputeState: String(row.dispute_state),
60928
+ validFrom: row.valid_from == null ? void 0 : String(row.valid_from),
60929
+ validTo: row.valid_to == null ? void 0 : String(row.valid_to),
60930
+ asOf: row.as_of == null ? void 0 : String(row.as_of),
60931
+ sourceFamily: String(row.source_family),
60932
+ reviewState: String(row.review_state),
60933
+ proposalId: String(row.proposal_id),
60934
+ createdByUserId: row.created_by_user_id == null ? null : Number(row.created_by_user_id),
60935
+ updatedByUserId: row.updated_by_user_id == null ? null : Number(row.updated_by_user_id),
60936
+ createdAt: String(row.created_at),
60937
+ updatedAt: String(row.updated_at)
60938
+ };
60939
+ }
60527
60940
  function commonsIndexStatements(entity, now) {
60528
60941
  return commonsIndexDocuments(entity, now).map((document2) => ({
60529
60942
  sql: `
@@ -60628,7 +61041,7 @@ function commonsIndexDocuments(entity, now) {
60628
61041
  return documents;
60629
61042
  }
60630
61043
  function commonsIndexDocumentId(entityId, documentType, documentKey) {
60631
- return `commons-index-${(0, import_node_crypto34.createHash)("sha256").update(`${entityId}
61044
+ return `commons-index-${(0, import_node_crypto35.createHash)("sha256").update(`${entityId}
60632
61045
  ${documentType}
60633
61046
  ${documentKey}`).digest("hex").slice(0, 32)}`;
60634
61047
  }
@@ -60803,14 +61216,14 @@ function normalizeArticleSections(sections) {
60803
61216
  return {
60804
61217
  relatedLinks: normalizeRelatedLinks(sections?.relatedLinks),
60805
61218
  notes: Array.isArray(sections?.notes) ? sections.notes.map((note) => ({
60806
- marker: optionalText(note.marker, 20) ?? void 0,
61219
+ marker: optionalText2(note.marker, 20) ?? void 0,
60807
61220
  body: requiredText(note.body, "notes.body", 1, 2e3)
60808
61221
  })).slice(0, 100) : [],
60809
61222
  citations: normalizeCitations(sections?.citations),
60810
61223
  externalLinks: Array.isArray(sections?.externalLinks) ? sections.externalLinks.map((link2) => ({
60811
61224
  title: requiredText(link2.title, "externalLinks.title", 1, 180),
60812
61225
  url: requiredText(link2.url, "externalLinks.url", 1, 2e3),
60813
- summary: optionalText(link2.summary, 300) ?? void 0
61226
+ summary: optionalText2(link2.summary, 300) ?? void 0
60814
61227
  })).slice(0, 100) : [],
60815
61228
  categories: uniqueStrings(sections?.categories ?? []).slice(0, 50)
60816
61229
  };
@@ -60819,7 +61232,7 @@ function normalizeRelatedLinks(relatedLinks) {
60819
61232
  if (!Array.isArray(relatedLinks)) return [];
60820
61233
  return relatedLinks.map((link2) => {
60821
61234
  const title = requiredText(link2.title, "relatedLinks.title", 1, 180);
60822
- const url = optionalText(link2.url, 2e3);
61235
+ const url = optionalText2(link2.url, 2e3);
60823
61236
  const slug2 = link2.slug ? normalizeSlug(link2.slug) : void 0;
60824
61237
  const entityId = normalizeEntityId(link2.entityId);
60825
61238
  const needsLink = link2.needsLink === true || !url && !slug2 && !entityId;
@@ -60828,9 +61241,9 @@ function normalizeRelatedLinks(relatedLinks) {
60828
61241
  url,
60829
61242
  slug: slug2,
60830
61243
  entityId,
60831
- relationship: optionalText(link2.relationship, 120) ?? void 0,
60832
- summary: optionalText(link2.summary, 300) ?? void 0,
60833
- imageUrl: optionalText(link2.imageUrl, 2e3) ?? void 0,
61244
+ relationship: optionalText2(link2.relationship, 120) ?? void 0,
61245
+ summary: optionalText2(link2.summary, 300) ?? void 0,
61246
+ imageUrl: optionalText2(link2.imageUrl, 2e3) ?? void 0,
60834
61247
  needsLink
60835
61248
  };
60836
61249
  }).slice(0, 100);
@@ -60839,20 +61252,20 @@ function normalizeCitations(citations) {
60839
61252
  if (!Array.isArray(citations)) return [];
60840
61253
  return citations.map((citation) => ({
60841
61254
  title: requiredText(citation.title, "citation.title", 1, 240),
60842
- url: optionalText(citation.url, 2e3) ?? void 0,
60843
- source: optionalText(citation.source, 240) ?? void 0,
60844
- note: optionalText(citation.note, 1e3) ?? void 0,
60845
- accessedAt: optionalText(citation.accessedAt, 80) ?? void 0
61255
+ url: optionalText2(citation.url, 2e3) ?? void 0,
61256
+ source: optionalText2(citation.source, 240) ?? void 0,
61257
+ note: optionalText2(citation.note, 1e3) ?? void 0,
61258
+ accessedAt: optionalText2(citation.accessedAt, 80) ?? void 0
60846
61259
  })).slice(0, 300);
60847
61260
  }
60848
61261
  function normalizeFeaturedImage(image) {
60849
61262
  if (!image?.url) return void 0;
60850
61263
  return {
60851
61264
  url: requiredText(image.url, "featuredImage.url", 1, 2e3),
60852
- alt: optionalText(image.alt, 500) ?? void 0,
60853
- caption: optionalText(image.caption, 1e3) ?? void 0,
60854
- sourceUrl: optionalText(image.sourceUrl, 2e3) ?? void 0,
60855
- license: optionalText(image.license, 240) ?? void 0,
61265
+ alt: optionalText2(image.alt, 500) ?? void 0,
61266
+ caption: optionalText2(image.caption, 1e3) ?? void 0,
61267
+ sourceUrl: optionalText2(image.sourceUrl, 2e3) ?? void 0,
61268
+ license: optionalText2(image.license, 240) ?? void 0,
60856
61269
  width: positiveInt(image.width),
60857
61270
  height: positiveInt(image.height)
60858
61271
  };
@@ -60861,11 +61274,11 @@ function normalizeMedia(media, featuredImage) {
60861
61274
  const normalized = Array.isArray(media) ? media.map((item) => ({
60862
61275
  type: item.type,
60863
61276
  url: requiredText(item.url, "media.url", 1, 2e3),
60864
- alt: optionalText(item.alt, 500) ?? void 0,
60865
- caption: optionalText(item.caption, 1e3) ?? void 0,
60866
- posterUrl: optionalText(item.posterUrl, 2e3) ?? void 0,
60867
- sourceUrl: optionalText(item.sourceUrl, 2e3) ?? void 0,
60868
- license: optionalText(item.license, 240) ?? void 0,
61277
+ alt: optionalText2(item.alt, 500) ?? void 0,
61278
+ caption: optionalText2(item.caption, 1e3) ?? void 0,
61279
+ posterUrl: optionalText2(item.posterUrl, 2e3) ?? void 0,
61280
+ sourceUrl: optionalText2(item.sourceUrl, 2e3) ?? void 0,
61281
+ license: optionalText2(item.license, 240) ?? void 0,
60869
61282
  width: positiveInt(item.width),
60870
61283
  height: positiveInt(item.height),
60871
61284
  durationSeconds: positiveInt(item.durationSeconds)
@@ -60895,28 +61308,28 @@ function normalizeMedia(media, featuredImage) {
60895
61308
  }
60896
61309
  function normalizeSource(source) {
60897
61310
  return {
60898
- originalUrl: optionalText(source?.originalUrl, 2e3) ?? void 0,
60899
- resolvedUrl: optionalText(source?.resolvedUrl, 2e3) ?? void 0,
60900
- sourceCanonicalUrl: optionalText(source?.sourceCanonicalUrl, 2e3) ?? void 0,
60901
- relCanonicalHref: optionalText(source?.relCanonicalHref, 2e3) ?? void 0,
60902
- sourceByline: optionalText(source?.sourceByline, 240) ?? void 0,
60903
- publisher: optionalText(source?.publisher, 240) ?? void 0,
61311
+ originalUrl: optionalText2(source?.originalUrl, 2e3) ?? void 0,
61312
+ resolvedUrl: optionalText2(source?.resolvedUrl, 2e3) ?? void 0,
61313
+ sourceCanonicalUrl: optionalText2(source?.sourceCanonicalUrl, 2e3) ?? void 0,
61314
+ relCanonicalHref: optionalText2(source?.relCanonicalHref, 2e3) ?? void 0,
61315
+ sourceByline: optionalText2(source?.sourceByline, 240) ?? void 0,
61316
+ publisher: optionalText2(source?.publisher, 240) ?? void 0,
60904
61317
  authors: uniqueStrings(source?.authors ?? []).slice(0, 20),
60905
- publishedAt: optionalText(source?.publishedAt, 80) ?? void 0,
60906
- capturedAt: optionalText(source?.capturedAt, 80) ?? void 0,
60907
- license: optionalText(source?.license, 240) ?? void 0,
60908
- rightsSummary: optionalText(source?.rightsSummary, 1e3) ?? void 0,
60909
- contentHash: optionalText(source?.contentHash, 200) ?? void 0
61318
+ publishedAt: optionalText2(source?.publishedAt, 80) ?? void 0,
61319
+ capturedAt: optionalText2(source?.capturedAt, 80) ?? void 0,
61320
+ license: optionalText2(source?.license, 240) ?? void 0,
61321
+ rightsSummary: optionalText2(source?.rightsSummary, 1e3) ?? void 0,
61322
+ contentHash: optionalText2(source?.contentHash, 200) ?? void 0
60910
61323
  };
60911
61324
  }
60912
61325
  function normalizeSeo(seo) {
60913
61326
  return {
60914
- canonicalUrl: optionalText(seo?.canonicalUrl, 2e3) ?? void 0,
60915
- relCanonical: optionalText(seo?.relCanonical, 2e3) ?? void 0,
60916
- metaTitle: optionalText(seo?.metaTitle, 240) ?? void 0,
60917
- metaDescription: optionalText(seo?.metaDescription, 500) ?? void 0,
60918
- ogImage: optionalText(seo?.ogImage, 2e3) ?? void 0,
60919
- schemaOrgType: optionalText(seo?.schemaOrgType, 80) ?? void 0,
61327
+ canonicalUrl: optionalText2(seo?.canonicalUrl, 2e3) ?? void 0,
61328
+ relCanonical: optionalText2(seo?.relCanonical, 2e3) ?? void 0,
61329
+ metaTitle: optionalText2(seo?.metaTitle, 240) ?? void 0,
61330
+ metaDescription: optionalText2(seo?.metaDescription, 500) ?? void 0,
61331
+ ogImage: optionalText2(seo?.ogImage, 2e3) ?? void 0,
61332
+ schemaOrgType: optionalText2(seo?.schemaOrgType, 80) ?? void 0,
60920
61333
  noIndex: seo?.noIndex === true
60921
61334
  };
60922
61335
  }
@@ -60925,37 +61338,37 @@ function normalizeRelatedEntities(related) {
60925
61338
  return related.map((item) => ({
60926
61339
  entityId: normalizeEntityId(item.entityId),
60927
61340
  title: requiredText(item.title, "relatedEntities.title", 1, 180),
60928
- relationship: optionalText(item.relationship, 120) ?? void 0,
61341
+ relationship: optionalText2(item.relationship, 120) ?? void 0,
60929
61342
  slug: item.slug ? normalizeSlug(item.slug) : void 0,
60930
- url: optionalText(item.url, 2e3) ?? void 0,
60931
- description: optionalText(item.description, 300) ?? void 0
61343
+ url: optionalText2(item.url, 2e3) ?? void 0,
61344
+ description: optionalText2(item.description, 300) ?? void 0
60932
61345
  })).slice(0, 200);
60933
61346
  }
60934
61347
  function sanitizeSearchFilters(filters) {
60935
61348
  return {
60936
- query: optionalText(filters.query, 300) ?? void 0,
61349
+ query: optionalText2(filters.query, 300) ?? void 0,
60937
61350
  entityType: filters.entityType ? normalizeEntityType(filters.entityType) : void 0,
60938
- tag: optionalText(filters.tag, 80) ?? void 0,
61351
+ tag: optionalText2(filters.tag, 80) ?? void 0,
60939
61352
  tags: uniqueStrings(filters.tags ?? []).slice(0, 20),
60940
- keyword: optionalText(filters.keyword, 120) ?? void 0,
61353
+ keyword: optionalText2(filters.keyword, 120) ?? void 0,
60941
61354
  keywords: uniqueStrings(filters.keywords ?? []).slice(0, 20),
60942
61355
  relatedEntityId: normalizeEntityId(filters.relatedEntityId),
60943
61356
  trailId: normalizeEntityId(filters.trailId),
60944
- sourceDomain: optionalText(filters.sourceDomain, 240) ?? void 0,
61357
+ sourceDomain: optionalText2(filters.sourceDomain, 240) ?? void 0,
60945
61358
  hasMedia: filters.hasMedia === true ? true : void 0,
60946
61359
  hasVideo: filters.hasVideo === true ? true : void 0,
60947
- publishedAfter: optionalText(filters.publishedAfter, 80) ?? void 0,
60948
- updatedAfter: optionalText(filters.updatedAfter, 80) ?? void 0,
60949
- filterId: optionalText(filters.filterId, 200) ?? void 0,
61360
+ publishedAfter: optionalText2(filters.publishedAfter, 80) ?? void 0,
61361
+ updatedAfter: optionalText2(filters.updatedAfter, 80) ?? void 0,
61362
+ filterId: optionalText2(filters.filterId, 200) ?? void 0,
60950
61363
  limit: clampNumber(filters.limit, 1, 100, 20),
60951
61364
  offset: clampNumber(filters.offset, 0, 1e4, 0)
60952
61365
  };
60953
61366
  }
60954
61367
  function sanitizeNeedsLinkFilters(filters) {
60955
61368
  return {
60956
- query: optionalText(filters.query, 300) ?? void 0,
61369
+ query: optionalText2(filters.query, 300) ?? void 0,
60957
61370
  entityType: filters.entityType ? normalizeEntityType(filters.entityType) : void 0,
60958
- tag: optionalText(filters.tag, 80) ?? void 0,
61371
+ tag: optionalText2(filters.tag, 80) ?? void 0,
60959
61372
  tags: uniqueStrings(filters.tags ?? []).slice(0, 20),
60960
61373
  sourceEntityId: normalizeEntityId(filters.sourceEntityId),
60961
61374
  sourceSlug: filters.sourceSlug ? normalizeSlug(filters.sourceSlug) : void 0,
@@ -60976,7 +61389,7 @@ function commonsIndexingPolicy() {
60976
61389
  storageScope: "platform_commons_graph",
60977
61390
  countsAgainstUserStorage: false,
60978
61391
  embedsPrivateUserVaults: false,
60979
- corpus: ["published Commons article body", "tags", "keywords", "JSON-LD metadata", "related entities", "See Also concepts marked needsLink"],
61392
+ corpus: ["published Commons article body", "tags", "keywords", "JSON-LD metadata", "related entities", "governed relationship claims", "See Also concepts marked needsLink"],
60980
61393
  excluded: ["comments", "comment threads", "reader alerts", "private reading-room state"],
60981
61394
  retrievalPattern: {
60982
61395
  lexicalFirst: ["title", "tags", "keywords", "source metadata", "article body", "See Also concepts"],
@@ -61052,7 +61465,7 @@ function searchableText(entity) {
61052
61465
  ].filter(Boolean).join("\n").toLowerCase();
61053
61466
  }
61054
61467
  function actorLabel(input, user) {
61055
- return optionalText(input.actorLabel, 120) || optionalText(user.name, 120) || `mcp-user-${user.id}`;
61468
+ return optionalText2(input.actorLabel, 120) || optionalText2(user.name, 120) || `mcp-user-${user.id}`;
61056
61469
  }
61057
61470
  function publicBaseUrl() {
61058
61471
  return (process.env.TRANSPARENT_COMMONS_PUBLIC_BASE_URL?.trim() || DEFAULT_COMMONS_BASE_URL).replace(/\/+$/, "");
@@ -61063,13 +61476,16 @@ function publicUrlForSlug(slug2) {
61063
61476
  function allocateEntityId() {
61064
61477
  return `TPW-Q${Date.now()}${Math.floor(Math.random() * 1e3).toString().padStart(3, "0")}`;
61065
61478
  }
61479
+ function allocateClaimId() {
61480
+ return `TPW-S${Date.now()}${Math.floor(Math.random() * 1e6).toString().padStart(6, "0")}`;
61481
+ }
61066
61482
  function normalizeEntityId(value) {
61067
- const text2 = optionalText(value, 80);
61483
+ const text2 = optionalText2(value, 80);
61068
61484
  if (!text2) return void 0;
61069
61485
  return text2.replace(/\s+/g, "").toUpperCase();
61070
61486
  }
61071
61487
  function normalizeEntityType(value) {
61072
- const raw = optionalText(value, 120) || DEFAULT_ENTITY_TYPE;
61488
+ const raw = optionalText2(value, 120) || DEFAULT_ENTITY_TYPE;
61073
61489
  const squashed = raw.replace(/[\s_-]+/g, "").toLowerCase();
61074
61490
  if (squashed === "publicarticle" || squashed === "article" || squashed === "item") return DEFAULT_ENTITY_TYPE;
61075
61491
  if (squashed === "trail" || squashed === "readingtrail") return "Trail";
@@ -61097,7 +61513,7 @@ function requiredText(value, field, min, max) {
61097
61513
  if (text2.length < min) throw new CommonsRepositoryError(`${field.replaceAll(".", "_")}_required`, `${field} must be at least ${min} characters.`);
61098
61514
  return text2.slice(0, max);
61099
61515
  }
61100
- function optionalText(value, max) {
61516
+ function optionalText2(value, max) {
61101
61517
  const text2 = String(value ?? "").trim();
61102
61518
  return text2 ? text2.slice(0, max) : void 0;
61103
61519
  }
@@ -61117,7 +61533,7 @@ function uniqueStrings(values) {
61117
61533
  const seen = /* @__PURE__ */ new Set();
61118
61534
  const out = [];
61119
61535
  for (const value of values) {
61120
- const text2 = optionalText(value, 120);
61536
+ const text2 = optionalText2(value, 120);
61121
61537
  if (!text2) continue;
61122
61538
  const key = text2.toLowerCase();
61123
61539
  if (seen.has(key)) continue;
@@ -61152,14 +61568,15 @@ function jsonLikeValue(value) {
61152
61568
  function escapeLike(value) {
61153
61569
  return value.replace(/[%_]/g, "");
61154
61570
  }
61155
- var import_node_crypto34, COMMONS_SCHEMA_VERSION, DEFAULT_COMMONS_BASE_URL, DEFAULT_ENTITY_TYPE, COMMONS_ENTITY_PROFILES, schemaReady2, CommonsRepositoryError;
61571
+ var import_node_crypto35, COMMONS_SCHEMA_VERSION, DEFAULT_COMMONS_BASE_URL, DEFAULT_ENTITY_TYPE, COMMONS_ENTITY_PROFILES, schemaReady2, CommonsRepositoryError;
61156
61572
  var init_commons_repository = __esm({
61157
61573
  "src/api/commons-repository.ts"() {
61158
61574
  "use strict";
61159
- import_node_crypto34 = require("crypto");
61575
+ import_node_crypto35 = require("crypto");
61160
61576
  init_db();
61161
61577
  init_rates();
61162
- COMMONS_SCHEMA_VERSION = "2026-08-04.3";
61578
+ init_commons_linksets();
61579
+ COMMONS_SCHEMA_VERSION = "2026-08-05.1";
61163
61580
  DEFAULT_COMMONS_BASE_URL = "https://transparent-commons.cc";
61164
61581
  DEFAULT_ENTITY_TYPE = "PublicArticle";
61165
61582
  COMMONS_ENTITY_PROFILES = {
@@ -61410,7 +61827,7 @@ async function claimCommonsPublication(input, user) {
61410
61827
  }
61411
61828
  const existingName = await getCommonsPublicationBySubdomain(subdomain);
61412
61829
  if (existingName) throw new CommonsPublicationError("publication_name_unavailable", "That publication name is already claimed.", 409);
61413
- const id = `tcpub_${(0, import_node_crypto35.randomUUID)()}`;
61830
+ const id = `tcpub_${(0, import_node_crypto36.randomUUID)()}`;
61414
61831
  const now = (/* @__PURE__ */ new Date()).toISOString();
61415
61832
  try {
61416
61833
  await getDb().execute({
@@ -61462,7 +61879,7 @@ async function publishCommonsEditorial(input, user) {
61462
61879
  const canonicalUrl = editionPublicUrl(subdomain, editionSlug);
61463
61880
  const rendered = renderEditorialReadingRoom(editionInput);
61464
61881
  const html = addPublicMetadata(rendered.html, canonicalUrl, publication.title);
61465
- const editionId = `tced_${(0, import_node_crypto35.randomUUID)()}`;
61882
+ const editionId = `tced_${(0, import_node_crypto36.randomUUID)()}`;
61466
61883
  const revision = (latest?.revision ?? 0) + 1;
61467
61884
  const now = (/* @__PURE__ */ new Date()).toISOString();
61468
61885
  await getDb().batch([
@@ -61486,7 +61903,7 @@ async function publishCommonsEditorial(input, user) {
61486
61903
  JSON.stringify(editionInput.articles),
61487
61904
  html,
61488
61905
  rendered.filename,
61489
- (0, import_node_crypto35.createHash)("sha256").update(html).digest("hex"),
61906
+ (0, import_node_crypto36.createHash)("sha256").update(html).digest("hex"),
61490
61907
  rendered.articleCount,
61491
61908
  rendered.wordCount,
61492
61909
  Buffer.byteLength(html),
@@ -61672,11 +62089,11 @@ function addPublicMetadata(html, canonicalUrl, publicationTitle) {
61672
62089
  "</head>"
61673
62090
  ].join("\n"));
61674
62091
  }
61675
- var import_node_crypto35, PUBLICATION_ROOT_DOMAIN, RESERVED_SUBDOMAINS, CommonsPublicationError;
62092
+ var import_node_crypto36, PUBLICATION_ROOT_DOMAIN, RESERVED_SUBDOMAINS, CommonsPublicationError;
61676
62093
  var init_commons_publication_repository = __esm({
61677
62094
  "src/api/commons-publication-repository.ts"() {
61678
62095
  "use strict";
61679
- import_node_crypto35 = require("crypto");
62096
+ import_node_crypto36 = require("crypto");
61680
62097
  init_db();
61681
62098
  init_commons_repository();
61682
62099
  init_render();
@@ -61785,6 +62202,7 @@ var init_commons_routes = __esm({
61785
62202
  import_zod51 = require("zod");
61786
62203
  init_api_auth();
61787
62204
  init_commons_repository();
62205
+ init_commons_linksets();
61788
62206
  init_listing_write_billing();
61789
62207
  init_commons_publication_repository();
61790
62208
  init_mcp_tool_schemas();
@@ -61879,6 +62297,7 @@ var init_commons_routes = __esm({
61879
62297
  url: import_zod51.z.string().url().optional(),
61880
62298
  description: import_zod51.z.string().max(300).optional()
61881
62299
  }).strict()).max(200).optional(),
62300
+ claims: import_zod51.z.array(CommonsClaimInputSchema).max(300).optional(),
61882
62301
  bodyMarkdown: import_zod51.z.string().max(5e5).optional(),
61883
62302
  contentSections: import_zod51.z.array(import_zod51.z.object({
61884
62303
  id: import_zod51.z.string().max(180).optional(),
@@ -61956,6 +62375,17 @@ var init_commons_routes = __esm({
61956
62375
  await ensureCommonsSchema();
61957
62376
  return c.json({ ok: true, data: commonsDatabaseReport() });
61958
62377
  });
62378
+ commonsApp.get("/profiles/relationships/v1", (c) => c.json({
62379
+ id: COMMONS_RELATIONSHIP_PROFILE,
62380
+ title: "Transparent Commons governed relationship linksets",
62381
+ mediaType: COMMONS_LINKSET_MEDIA_TYPE,
62382
+ claimAuthority: "MCP Scraper authenticated proposal and contribution ledger",
62383
+ anchorPolicy: "Every link context is an absolute canonical Transparent Commons wiki URL.",
62384
+ predicatePolicy: "Predicates are curated registered link relations or absolute HTTPS extension relation URIs.",
62385
+ publicationPolicy: "Only approved, active, non-deprecated claims whose dispute state is undisputed or attributed are projected.",
62386
+ trustPolicy: "A third-party target is an asserted relationship, not an endorsement or proof that the target agrees.",
62387
+ source: "https://www.rfc-editor.org/rfc/rfc9264.html"
62388
+ }));
61959
62389
  commonsApp.post("/publications/prepare", auth2, async (c) => {
61960
62390
  const parsed = PreparePublicationSchema.safeParse(await c.req.json().catch(() => ({})));
61961
62391
  if (!parsed.success) return validationError(c, parsed.error);
@@ -62086,11 +62516,32 @@ var init_commons_routes = __esm({
62086
62516
  commonsApp.get("/entities/:idOrSlug", async (c) => {
62087
62517
  const entity = await getCommonsEntity(c.req.param("idOrSlug"));
62088
62518
  if (!entity) return c.json({ ok: false, error: "entity_not_found", message: "No published Commons entity matched that id or slug." }, 404);
62519
+ c.header("Link", commonsLinksetDiscoveryHeader(entity.id));
62089
62520
  return c.json({ ok: true, data: entity });
62090
62521
  });
62522
+ commonsApp.get("/entities/:idOrSlug/claims", async (c) => {
62523
+ const result = await getCommonsEntityLinkset(c.req.param("idOrSlug"));
62524
+ if (!result) return c.json({ ok: false, error: "entity_not_found", message: "No published Commons entity matched that id or slug." }, 404);
62525
+ c.header("Link", commonsLinksetDiscoveryHeader(result.entity.id));
62526
+ return c.json({ ok: true, data: { entity: result.entity, claims: result.claims, linksetUrl: result.linksetUrl } });
62527
+ });
62528
+ commonsApp.get("/entities/:idOrSlug/linkset", async (c) => {
62529
+ const result = await getCommonsEntityLinkset(c.req.param("idOrSlug"));
62530
+ if (!result) return c.json({ ok: false, error: "entity_not_found", message: "No published Commons entity matched that id or slug." }, 404);
62531
+ c.header("Content-Type", `${COMMONS_LINKSET_MEDIA_TYPE}; profile="${COMMONS_RELATIONSHIP_PROFILE}"`);
62532
+ c.header("ETag", result.etag);
62533
+ c.header("Link", `<${COMMONS_RELATIONSHIP_PROFILE}>; rel="profile"`);
62534
+ c.header("Cache-Control", "public, max-age=60, s-maxage=300");
62535
+ if (c.req.header("If-None-Match") === result.etag) return c.body(null, 304);
62536
+ if (c.req.query("envelope") === "true") {
62537
+ return c.json({ ok: true, data: { ...result, document: result.document } });
62538
+ }
62539
+ return c.body(JSON.stringify(result.document));
62540
+ });
62091
62541
  commonsApp.get("/entities/:idOrSlug/wiki-page", async (c) => {
62092
62542
  const entity = await getCommonsEntity(c.req.param("idOrSlug"));
62093
62543
  if (!entity) return c.json({ ok: false, error: "entity_not_found", message: "No published Commons entity matched that id or slug." }, 404);
62544
+ c.header("Link", commonsLinksetDiscoveryHeader(entity.id));
62094
62545
  return c.json({ ok: true, data: entityToWikiPage(entity) });
62095
62546
  });
62096
62547
  commonsApp.get("/entities/:idOrSlug/json-ld", async (c) => {
@@ -62106,6 +62557,7 @@ var init_commons_routes = __esm({
62106
62557
  commonsApp.get("/wiki/:slug", async (c) => {
62107
62558
  const entity = await getCommonsEntity(c.req.param("slug"));
62108
62559
  if (!entity) return c.json({ ok: false, error: "page_not_found", message: "No published Commons wiki page matched that slug." }, 404);
62560
+ c.header("Link", commonsLinksetDiscoveryHeader(entity.id));
62109
62561
  return c.json({
62110
62562
  ok: true,
62111
62563
  data: {
@@ -62786,7 +63238,7 @@ async function migrateAnalytics() {
62786
63238
  }
62787
63239
  function normalizeSlug2(value) {
62788
63240
  const slug2 = value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
62789
- return slug2 || `site-${(0, import_node_crypto36.randomBytes)(4).toString("hex")}`;
63241
+ return slug2 || `site-${(0, import_node_crypto37.randomBytes)(4).toString("hex")}`;
62790
63242
  }
62791
63243
  function normalizeObservedHostname(origin) {
62792
63244
  if (!origin || origin === "null") return null;
@@ -62799,7 +63251,7 @@ function normalizeObservedHostname(origin) {
62799
63251
  }
62800
63252
  }
62801
63253
  function publicPixelId() {
62802
- return `px_${(0, import_node_crypto36.randomBytes)(18).toString("base64url")}`;
63254
+ return `px_${(0, import_node_crypto37.randomBytes)(18).toString("base64url")}`;
62803
63255
  }
62804
63256
  function mapRows(rows) {
62805
63257
  return rows;
@@ -62831,7 +63283,7 @@ async function requireEditor(client2, siteId, userId) {
62831
63283
  async function createAnalyticsSite(input) {
62832
63284
  const db = getAnalyticsPool();
62833
63285
  const client2 = await db.connect();
62834
- const id = (0, import_node_crypto36.randomUUID)();
63286
+ const id = (0, import_node_crypto37.randomUUID)();
62835
63287
  const baseSlug = normalizeSlug2(input.slug || input.name);
62836
63288
  try {
62837
63289
  await client2.query("BEGIN");
@@ -62847,7 +63299,7 @@ async function createAnalyticsSite(input) {
62847
63299
  } catch (error) {
62848
63300
  const code = error.code;
62849
63301
  if (code !== "23505" || attempt === 2) throw error;
62850
- slug2 = `${baseSlug}-${(0, import_node_crypto36.randomBytes)(2).toString("hex")}`;
63302
+ slug2 = `${baseSlug}-${(0, import_node_crypto37.randomBytes)(2).toString("hex")}`;
62851
63303
  }
62852
63304
  }
62853
63305
  await client2.query(
@@ -63062,7 +63514,7 @@ async function createAnalyticsPixel(input) {
63062
63514
  VALUES ($1, $2, $3, $4, $5)
63063
63515
  RETURNING id, site_id, public_id, name, environment, status, created_at::text, NULL::text AS last_event_at`,
63064
63516
  [
63065
- (0, import_node_crypto36.randomUUID)(),
63517
+ (0, import_node_crypto37.randomUUID)(),
63066
63518
  input.siteId,
63067
63519
  publicPixelId(),
63068
63520
  input.name.trim(),
@@ -63139,7 +63591,7 @@ async function setAnalyticsPixelDomainState(input) {
63139
63591
  SELECT $1, p.id, $4, $5 FROM analytics_pixels p WHERE p.id = $2 AND p.site_id = $3
63140
63592
  ON CONFLICT(pixel_id, hostname) DO UPDATE SET state = EXCLUDED.state, updated_at = now()
63141
63593
  RETURNING id`,
63142
- [(0, import_node_crypto36.randomUUID)(), input.pixelId, input.siteId, hostname, input.state]
63594
+ [(0, import_node_crypto37.randomUUID)(), input.pixelId, input.siteId, hostname, input.state]
63143
63595
  );
63144
63596
  if (!result.rowCount)
63145
63597
  throw new AnalyticsRepositoryError(
@@ -63183,7 +63635,7 @@ function sanitizeAnalyticsProperties(value) {
63183
63635
  }
63184
63636
  async function ingestAnalyticsEvents(input) {
63185
63637
  const db = getAnalyticsPool();
63186
- const requestId = `air_${(0, import_node_crypto36.randomUUID)()}`;
63638
+ const requestId = `air_${(0, import_node_crypto37.randomUUID)()}`;
63187
63639
  const hostname = normalizeObservedHostname(input.origin);
63188
63640
  const pixelResult = await db.query(
63189
63641
  `SELECT p.id, p.site_id, p.status,
@@ -63204,7 +63656,7 @@ async function ingestAnalyticsEvents(input) {
63204
63656
  `INSERT INTO analytics_ingestion_receipts(id, request_id, site_id, pixel_id, hostname, rejected_count, reason_codes)
63205
63657
  VALUES ($1, $2, $3, $4, $5, $6, $7::jsonb)`,
63206
63658
  [
63207
- (0, import_node_crypto36.randomUUID)(),
63659
+ (0, import_node_crypto37.randomUUID)(),
63208
63660
  requestId,
63209
63661
  pixel?.site_id ?? null,
63210
63662
  pixel?.id ?? null,
@@ -63229,7 +63681,7 @@ async function ingestAnalyticsEvents(input) {
63229
63681
  `INSERT INTO analytics_ingestion_receipts(id, request_id, site_id, pixel_id, hostname, rejected_count, reason_codes)
63230
63682
  VALUES ($1, $2, $3, $4, $5, $6, $7::jsonb)`,
63231
63683
  [
63232
- (0, import_node_crypto36.randomUUID)(),
63684
+ (0, import_node_crypto37.randomUUID)(),
63233
63685
  requestId,
63234
63686
  pixel.site_id,
63235
63687
  pixel.id,
@@ -63254,7 +63706,7 @@ async function ingestAnalyticsEvents(input) {
63254
63706
  `INSERT INTO analytics_ingestion_receipts(id, request_id, site_id, pixel_id, rejected_count, reason_codes)
63255
63707
  VALUES ($1, $2, $3, $4, $5, $6::jsonb)`,
63256
63708
  [
63257
- (0, import_node_crypto36.randomUUID)(),
63709
+ (0, import_node_crypto37.randomUUID)(),
63258
63710
  requestId,
63259
63711
  pixel.site_id,
63260
63712
  pixel.id,
@@ -63278,7 +63730,7 @@ async function ingestAnalyticsEvents(input) {
63278
63730
  ON CONFLICT(pixel_id, hostname) DO UPDATE
63279
63731
  SET last_seen_at = now(), updated_at = now()
63280
63732
  RETURNING state`,
63281
- [(0, import_node_crypto36.randomUUID)(), pixel.id, hostname]
63733
+ [(0, import_node_crypto37.randomUUID)(), pixel.id, hostname]
63282
63734
  );
63283
63735
  if (domainResult.rows[0]?.state !== "approved") {
63284
63736
  await db.query(
@@ -63292,7 +63744,7 @@ async function ingestAnalyticsEvents(input) {
63292
63744
  `INSERT INTO analytics_ingestion_receipts(id, request_id, site_id, pixel_id, hostname, rejected_count, reason_codes)
63293
63745
  VALUES ($1, $2, $3, $4, $5, $6, $7::jsonb)`,
63294
63746
  [
63295
- (0, import_node_crypto36.randomUUID)(),
63747
+ (0, import_node_crypto37.randomUUID)(),
63296
63748
  requestId,
63297
63749
  pixel.site_id,
63298
63750
  pixel.id,
@@ -63341,7 +63793,7 @@ async function ingestAnalyticsEvents(input) {
63341
63793
  $23, $24, $25, $26, $27, $28, $29, $30, $31
63342
63794
  ) ON CONFLICT(site_id, event_id) DO NOTHING`,
63343
63795
  [
63344
- (0, import_node_crypto36.randomUUID)(),
63796
+ (0, import_node_crypto37.randomUUID)(),
63345
63797
  event2.eventId,
63346
63798
  pixel.site_id,
63347
63799
  pixel.id,
@@ -63397,7 +63849,7 @@ async function ingestAnalyticsEvents(input) {
63397
63849
  id, request_id, site_id, pixel_id, hostname, accepted_count, rejected_count, reason_codes
63398
63850
  ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8::jsonb)`,
63399
63851
  [
63400
- (0, import_node_crypto36.randomUUID)(),
63852
+ (0, import_node_crypto37.randomUUID)(),
63401
63853
  requestId,
63402
63854
  pixel.site_id,
63403
63855
  pixel.id,
@@ -63429,7 +63881,7 @@ function normalizeGeographyCode(value, max) {
63429
63881
  return normalized && /^[A-Z0-9-]+$/.test(normalized) ? normalized.slice(0, max) : null;
63430
63882
  }
63431
63883
  function pageFingerprint(scope, siteId, filters) {
63432
- return (0, import_node_crypto36.createHash)("sha256").update(JSON.stringify({ scope, siteId, filters })).digest("base64url").slice(0, 18);
63884
+ return (0, import_node_crypto37.createHash)("sha256").update(JSON.stringify({ scope, siteId, filters })).digest("base64url").slice(0, 18);
63433
63885
  }
63434
63886
  function decodePageOffset(cursor, fingerprint) {
63435
63887
  if (!cursor) return 0;
@@ -63479,7 +63931,7 @@ async function createAnalyticsConversion(input) {
63479
63931
  404
63480
63932
  );
63481
63933
  }
63482
- const id = (0, import_node_crypto36.randomUUID)();
63934
+ const id = (0, import_node_crypto37.randomUUID)();
63483
63935
  const resolvedPerson = input.sessionId ? await db.query(
63484
63936
  `SELECT e.person_id FROM analytics_identity_nodes n JOIN analytics_identity_edges e ON e.identity_node_id = n.id
63485
63937
  WHERE n.site_id = $1 AND n.kind = 'session_id' AND n.value_hmac = $2 ORDER BY e.confidence DESC LIMIT 1`,
@@ -64154,7 +64606,7 @@ async function createAnalyticsCampaignLink(input) {
64154
64606
  404
64155
64607
  );
64156
64608
  }
64157
- const shortCode = (input.shortCode?.trim().toLowerCase().replace(/[^a-z0-9_-]/g, "-") || (0, import_node_crypto36.randomBytes)(5).toString("base64url").toLowerCase()).slice(0, 48);
64609
+ const shortCode = (input.shortCode?.trim().toLowerCase().replace(/[^a-z0-9_-]/g, "-") || (0, import_node_crypto37.randomBytes)(5).toString("base64url").toLowerCase()).slice(0, 48);
64158
64610
  try {
64159
64611
  const result = await db.query(
64160
64612
  `INSERT INTO analytics_campaign_links(
@@ -64163,7 +64615,7 @@ async function createAnalyticsCampaignLink(input) {
64163
64615
  ) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15)
64164
64616
  RETURNING *, 0::int AS click_count`,
64165
64617
  [
64166
- (0, import_node_crypto36.randomUUID)(),
64618
+ (0, import_node_crypto37.randomUUID)(),
64167
64619
  input.siteId,
64168
64620
  input.pixelId ?? null,
64169
64621
  input.name.trim(),
@@ -64234,7 +64686,7 @@ async function resolveAnalyticsCampaignLink(shortCode, referrer) {
64234
64686
  if (!row) return null;
64235
64687
  await db.query(
64236
64688
  `INSERT INTO analytics_campaign_clicks(id, link_id, referrer) VALUES ($1, $2, $3)`,
64237
- [(0, import_node_crypto36.randomUUID)(), row.id, normalizeAnalyticsUrl(referrer || void 0)]
64689
+ [(0, import_node_crypto37.randomUUID)(), row.id, normalizeAnalyticsUrl(referrer || void 0)]
64238
64690
  );
64239
64691
  return buildTaggedCampaignUrl(row);
64240
64692
  }
@@ -64252,14 +64704,14 @@ async function createAnalyticsForm(input) {
64252
64704
  404
64253
64705
  );
64254
64706
  const baseSlug = normalizeSlug2(input.name);
64255
- const slug2 = `${baseSlug}-${(0, import_node_crypto36.randomBytes)(3).toString("hex")}`;
64256
- const publicId = `form_${(0, import_node_crypto36.randomBytes)(18).toString("base64url")}`;
64707
+ const slug2 = `${baseSlug}-${(0, import_node_crypto37.randomBytes)(3).toString("hex")}`;
64708
+ const publicId = `form_${(0, import_node_crypto37.randomBytes)(18).toString("base64url")}`;
64257
64709
  const result = await db.query(
64258
64710
  `INSERT INTO analytics_forms(id, public_id, site_id, pixel_id, name, slug, fields, brand, submit_label, success_message, redirect_url, consent_text, status, created_by_user_id)
64259
64711
  VALUES ($1,$2,$3,$4,$5,$6,$7::jsonb,$8::jsonb,$9,$10,$11,$12,$13,$14)
64260
64712
  RETURNING *, 0::int AS submission_count`,
64261
64713
  [
64262
- (0, import_node_crypto36.randomUUID)(),
64714
+ (0, import_node_crypto37.randomUUID)(),
64263
64715
  publicId,
64264
64716
  input.siteId,
64265
64717
  input.pixelId,
@@ -64304,7 +64756,7 @@ async function getPublicAnalyticsForm(publicId) {
64304
64756
  return result.rows[0] ?? null;
64305
64757
  }
64306
64758
  async function recordAnalyticsFormSubmission(input) {
64307
- const id = (0, import_node_crypto36.randomUUID)();
64759
+ const id = (0, import_node_crypto37.randomUUID)();
64308
64760
  await getAnalyticsPool().query(
64309
64761
  `INSERT INTO analytics_form_submissions(id, form_id, site_id, pixel_id, visitor_id, session_id, crm_person_ref, source, medium, campaign, crm_delivery_status, click_ids)
64310
64762
  VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12::jsonb)`,
@@ -64335,7 +64787,7 @@ function sanitizeClickIds(value) {
64335
64787
  return output;
64336
64788
  }
64337
64789
  function identityHmac(kind, value) {
64338
- return (0, import_node_crypto36.createHmac)("sha256", getSessionSecret()).update(`${kind}:${value.trim().toLowerCase()}`).digest("hex");
64790
+ return (0, import_node_crypto37.createHmac)("sha256", getSessionSecret()).update(`${kind}:${value.trim().toLowerCase()}`).digest("hex");
64339
64791
  }
64340
64792
  async function linkAnalyticsFormIdentity(input) {
64341
64793
  const client2 = await getAnalyticsPool().connect();
@@ -64344,7 +64796,7 @@ async function linkAnalyticsFormIdentity(input) {
64344
64796
  const person = await client2.query(
64345
64797
  `INSERT INTO analytics_people(id, site_id, crm_person_ref) VALUES ($1,$2,$3)
64346
64798
  ON CONFLICT(site_id, crm_person_ref) DO UPDATE SET last_seen_at = now() RETURNING id`,
64347
- [(0, import_node_crypto36.randomUUID)(), input.siteId, input.crmPersonRef]
64799
+ [(0, import_node_crypto37.randomUUID)(), input.siteId, input.crmPersonRef]
64348
64800
  );
64349
64801
  const personId = person.rows[0].id;
64350
64802
  const signals = [];
@@ -64391,7 +64843,7 @@ async function linkAnalyticsFormIdentity(input) {
64391
64843
  `INSERT INTO analytics_identity_nodes(id, site_id, kind, value_hmac) VALUES ($1,$2,$3,$4)
64392
64844
  ON CONFLICT(site_id, kind, value_hmac) DO UPDATE SET last_seen_at = now() RETURNING id`,
64393
64845
  [
64394
- (0, import_node_crypto36.randomUUID)(),
64846
+ (0, import_node_crypto37.randomUUID)(),
64395
64847
  input.siteId,
64396
64848
  signal.kind,
64397
64849
  identityHmac(signal.kind, signal.value)
@@ -64402,7 +64854,7 @@ async function linkAnalyticsFormIdentity(input) {
64402
64854
  VALUES ($1,$2,$3,$4,$5,$6)
64403
64855
  ON CONFLICT(person_id, identity_node_id, evidence_kind) DO UPDATE SET last_seen_at = now(), confidence = greatest(analytics_identity_edges.confidence, EXCLUDED.confidence)`,
64404
64856
  [
64405
- (0, import_node_crypto36.randomUUID)(),
64857
+ (0, import_node_crypto37.randomUUID)(),
64406
64858
  input.siteId,
64407
64859
  personId,
64408
64860
  node.rows[0].id,
@@ -64500,7 +64952,7 @@ async function createAnalyticsCrmImport(input) {
64500
64952
  const db = getAnalyticsPool();
64501
64953
  await requireEditor(db, input.siteId, input.userId);
64502
64954
  const client2 = await db.connect();
64503
- const id = (0, import_node_crypto36.randomUUID)();
64955
+ const id = (0, import_node_crypto37.randomUUID)();
64504
64956
  try {
64505
64957
  await client2.query("BEGIN");
64506
64958
  await client2.query(
@@ -64520,7 +64972,7 @@ async function createAnalyticsCrmImport(input) {
64520
64972
  await client2.query(
64521
64973
  `INSERT INTO analytics_crm_import_rows(id, import_id, crm_person_ref, payload_ciphertext)
64522
64974
  VALUES ($1,$2,$3,$4) ON CONFLICT(import_id, crm_person_ref) DO NOTHING`,
64523
- [(0, import_node_crypto36.randomUUID)(), id, row.crmPersonRef, row.payloadCiphertext]
64975
+ [(0, import_node_crypto37.randomUUID)(), id, row.crmPersonRef, row.payloadCiphertext]
64524
64976
  );
64525
64977
  }
64526
64978
  await client2.query("COMMIT");
@@ -64559,7 +65011,7 @@ async function createAnalyticsActivationDestination(input) {
64559
65011
  `INSERT INTO analytics_activation_destinations(id, site_id, platform, name, connection_ref, external_dataset_id, event_mapping, created_by_user_id)
64560
65012
  VALUES ($1,$2,$3,$4,$5,$6,$7::jsonb,$8) RETURNING *`,
64561
65013
  [
64562
- (0, import_node_crypto36.randomUUID)(),
65014
+ (0, import_node_crypto37.randomUUID)(),
64563
65015
  input.siteId,
64564
65016
  input.platform,
64565
65017
  input.name.trim(),
@@ -64611,7 +65063,7 @@ async function queueAnalyticsActivation(input) {
64611
65063
  `INSERT INTO analytics_activation_jobs(id, destination_id, conversion_id, person_id, payload_ciphertext)
64612
65064
  VALUES ($1,$2,$3,$4,$5) ON CONFLICT(destination_id, conversion_id) DO NOTHING`,
64613
65065
  [
64614
- (0, import_node_crypto36.randomUUID)(),
65066
+ (0, import_node_crypto37.randomUUID)(),
64615
65067
  destination.id,
64616
65068
  input.conversionId,
64617
65069
  input.personId ?? null,
@@ -64623,7 +65075,7 @@ async function queueAnalyticsActivation(input) {
64623
65075
  return queued;
64624
65076
  }
64625
65077
  async function queueAnalyticsFormDelivery(input) {
64626
- const id = (0, import_node_crypto36.randomUUID)();
65078
+ const id = (0, import_node_crypto37.randomUUID)();
64627
65079
  await getAnalyticsPool().query(
64628
65080
  `INSERT INTO analytics_form_delivery_jobs(id, submission_id, owner_user_id, payload_ciphertext, last_error_code)
64629
65081
  VALUES ($1,$2,$3,$4,$5)`,
@@ -64750,7 +65202,7 @@ async function analyticsHealth(siteId, userId) {
64750
65202
  }
64751
65203
  async function refreshAnalyticsDailyRollups(input) {
64752
65204
  const db = getAnalyticsPool();
64753
- const runId = (0, import_node_crypto36.randomUUID)();
65205
+ const runId = (0, import_node_crypto37.randomUUID)();
64754
65206
  await db.query(
64755
65207
  `INSERT INTO analytics_rollup_runs(id, window_start, window_end, status) VALUES ($1, $2, $3, 'running')`,
64756
65208
  [runId, input.start, input.end]
@@ -64913,7 +65365,7 @@ async function createAnalyticsExport(input) {
64913
65365
  `Generated ${(/* @__PURE__ */ new Date()).toISOString()} from the governed ${input.report} report contract.`
64914
65366
  ].join("\n");
64915
65367
  }
64916
- const id = (0, import_node_crypto36.randomUUID)();
65368
+ const id = (0, import_node_crypto37.randomUUID)();
64917
65369
  const inserted = await getAnalyticsPool().query(
64918
65370
  `INSERT INTO analytics_exports(id, site_id, requested_by_user_id, idempotency_key, report, format, filters, content)
64919
65371
  VALUES ($1, $2, $3, $4, $5, $6, $7::jsonb, $8)
@@ -64946,11 +65398,11 @@ async function createAnalyticsExport(input) {
64946
65398
  }
64947
65399
  return describeArtifact(replay.rows[0]);
64948
65400
  }
64949
- var import_node_crypto36, import_pg, AnalyticsRepositoryError, pool2, blockedPropertyName, inferredFamilySql, clickIdKeys;
65401
+ var import_node_crypto37, import_pg, AnalyticsRepositoryError, pool2, blockedPropertyName, inferredFamilySql, clickIdKeys;
64950
65402
  var init_analytics_repository = __esm({
64951
65403
  "src/api/analytics-repository.ts"() {
64952
65404
  "use strict";
64953
- import_node_crypto36 = require("crypto");
65405
+ import_node_crypto37 = require("crypto");
64954
65406
  import_pg = require("pg");
64955
65407
  init_session();
64956
65408
  init_analytics_attribution();
@@ -65171,8 +65623,8 @@ function dashboardCallbackUrl() {
65171
65623
  }
65172
65624
  async function createThorbitConnectUrl(userId) {
65173
65625
  if (!bridgeConfigured()) throw new Error("Thorbit X-Ray account bridge is not configured");
65174
- const state = (0, import_node_crypto37.randomBytes)(32).toString("base64url");
65175
- const stateHash = (0, import_node_crypto37.createHash)("sha256").update(state).digest("hex");
65626
+ const state = (0, import_node_crypto38.randomBytes)(32).toString("base64url");
65627
+ const stateHash = (0, import_node_crypto38.createHash)("sha256").update(state).digest("hex");
65176
65628
  await getAnalyticsPool().query(
65177
65629
  `INSERT INTO analytics_thorbit_connect_states(state_hash,user_id,expires_at)
65178
65630
  VALUES ($1,$2,now()+interval '10 minutes')
@@ -65187,9 +65639,9 @@ async function createThorbitConnectUrl(userId) {
65187
65639
  function verifyThorbitAssertion(token4) {
65188
65640
  const [encoded, signature] = token4.split(".");
65189
65641
  if (!encoded || !signature || !bridgeConfigured()) throw new Error("Invalid Thorbit assertion");
65190
- const expected = (0, import_node_crypto37.createHmac)("sha256", bridgeSecret()).update(encoded).digest();
65642
+ const expected = (0, import_node_crypto38.createHmac)("sha256", bridgeSecret()).update(encoded).digest();
65191
65643
  const actual = Buffer.from(signature, "base64url");
65192
- if (actual.length !== expected.length || !(0, import_node_crypto37.timingSafeEqual)(actual, expected)) {
65644
+ if (actual.length !== expected.length || !(0, import_node_crypto38.timingSafeEqual)(actual, expected)) {
65193
65645
  throw new Error("Invalid Thorbit assertion signature");
65194
65646
  }
65195
65647
  const parsed = AssertionSchema.safeParse(
@@ -65201,7 +65653,7 @@ function verifyThorbitAssertion(token4) {
65201
65653
  return parsed.data.entitlement;
65202
65654
  }
65203
65655
  async function consumeThorbitConnectCallback(input) {
65204
- const stateHash = (0, import_node_crypto37.createHash)("sha256").update(input.state).digest("hex");
65656
+ const stateHash = (0, import_node_crypto38.createHash)("sha256").update(input.state).digest("hex");
65205
65657
  const client2 = await getAnalyticsPool().connect();
65206
65658
  try {
65207
65659
  await client2.query("BEGIN");
@@ -65241,11 +65693,11 @@ async function disconnectAnalyticsEntitlement(userId) {
65241
65693
  [userId]
65242
65694
  );
65243
65695
  }
65244
- var import_node_crypto37, import_zod52, THORBIT_PRODUCT_URL, REFRESH_INTERVAL_MS, ELIGIBLE_GRACE_MS, TRIAL_LENGTH_MS, ThorbitEntitlementSchema, AssertionSchema;
65696
+ var import_node_crypto38, import_zod52, THORBIT_PRODUCT_URL, REFRESH_INTERVAL_MS, ELIGIBLE_GRACE_MS, TRIAL_LENGTH_MS, ThorbitEntitlementSchema, AssertionSchema;
65245
65697
  var init_analytics_entitlement = __esm({
65246
65698
  "src/api/analytics-entitlement.ts"() {
65247
65699
  "use strict";
65248
- import_node_crypto37 = require("crypto");
65700
+ import_node_crypto38 = require("crypto");
65249
65701
  import_zod52 = require("zod");
65250
65702
  init_analytics_repository();
65251
65703
  THORBIT_PRODUCT_URL = "https://thorbit.ai";
@@ -65382,14 +65834,14 @@ function renderPublicForm(form, placementUrl) {
65382
65834
  const brand = form.brand;
65383
65835
  return `<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><style>:root{font-family:ui-sans-serif,system-ui;color:${escapeHtml7(brand.textColor)};background:${escapeHtml7(brand.backgroundColor)}}*{box-sizing:border-box}body{margin:0;padding:18px}form{display:grid;gap:14px}label{display:grid;gap:6px;font-size:13px;font-weight:650}.check{grid-template-columns:auto 1fr;align-items:center}.check span{grid-column:2}.check input{grid-column:1;grid-row:1}input,textarea,select{width:100%;min-height:44px;padding:10px 12px;border:1px solid #ccd3df;border-radius:${brand.radius}px;background:white;color:inherit;font:inherit}textarea{min-height:110px;resize:vertical}button{min-height:46px;border:0;border-radius:${brand.radius}px;color:white;background:${escapeHtml7(brand.primaryColor)};font:inherit;font-weight:750;cursor:pointer}.consent{margin:0;color:#667085;font-size:11px;line-height:1.45}.notice{display:none;padding:12px;border-radius:${brand.radius}px;background:#edf8f2;color:#17613c}.hp{position:absolute!important;left:-9999px!important}</style></head><body><form id="mcp-form">${fields}<label class="hp">Website<input name="website" autocomplete="off" tabindex="-1"></label>${form.consent_text ? `<p class="consent">${escapeHtml7(form.consent_text)}</p>` : ""}<button>${escapeHtml7(form.submit_label)}</button><div class="notice" role="status"></div></form><script>(()=>{const form=document.querySelector('#mcp-form'),notice=form.querySelector('.notice'),q=new URLSearchParams(location.search);form.addEventListener('submit',async event=>{event.preventDefault();const button=form.querySelector('button');button.disabled=true;const raw=Object.fromEntries(new FormData(form).entries()),website=String(raw.website||''),clickIds={};delete raw.website;for(const k of ['fbclid','gclid','gbraid','wbraid','ttclid','rdt_cid','msclkid']){const v=q.get(k);if(v)clickIds[k]=v}try{const response=await fetch('/analytics/forms/${escapeHtml7(form.public_id)}/submissions',{method:'POST',headers:{'content-type':'application/json'},body:JSON.stringify({data:raw,website,placementUrl:${JSON.stringify(placementUrl)},visitorId:q.get('visitor')||undefined,sessionId:q.get('session')||undefined,source:q.get('source')||undefined,medium:q.get('medium')||undefined,campaign:q.get('campaign')||undefined,clickIds})});if(!response.ok)throw new Error('submit');notice.textContent=${JSON.stringify(form.success_message)};notice.style.display='block';form.reset();${form.redirect_url ? `setTimeout(()=>{top.location.href=${JSON.stringify(form.redirect_url)}},700);` : ""}}catch{notice.textContent='Your response could not be submitted. Please try again.';notice.style.display='block'}finally{button.disabled=false}})})()</script></body></html>`;
65384
65836
  }
65385
- var import_hono32, import_factory6, import_zod53, import_node_crypto38, import_papaparse4, analyticsApp, auth3, entitlementGuard, ThorbitApiKeySchema, ThorbitCallbackSchema, SiteInputSchema, PixelInputSchema, PixelUpdateSchema, EventSchema, IngestionSchema, ConversionSchema, ExportSchema2, CampaignLinkSchema, FormFieldSchema, FormInputSchema, FormSubmissionSchema, CrmImportSchema, ActivationDestinationSchema, BusinessModelSchema, AdSpendSchema;
65837
+ var import_hono32, import_factory6, import_zod53, import_node_crypto39, import_papaparse4, analyticsApp, auth3, entitlementGuard, ThorbitApiKeySchema, ThorbitCallbackSchema, SiteInputSchema, PixelInputSchema, PixelUpdateSchema, EventSchema, IngestionSchema, ConversionSchema, ExportSchema2, CampaignLinkSchema, FormFieldSchema, FormInputSchema, FormSubmissionSchema, CrmImportSchema, ActivationDestinationSchema, BusinessModelSchema, AdSpendSchema;
65386
65838
  var init_analytics_routes = __esm({
65387
65839
  "src/api/analytics-routes.ts"() {
65388
65840
  "use strict";
65389
65841
  import_hono32 = require("hono");
65390
65842
  import_factory6 = require("hono/factory");
65391
65843
  import_zod53 = require("zod");
65392
- import_node_crypto38 = require("crypto");
65844
+ import_node_crypto39 = require("crypto");
65393
65845
  import_papaparse4 = __toESM(require("papaparse"), 1);
65394
65846
  init_api_auth();
65395
65847
  init_db();
@@ -65718,7 +66170,7 @@ var init_analytics_routes = __esm({
65718
66170
  const lastName = typeof data.last_name === "string" ? data.last_name.trim() : "";
65719
66171
  const fullName = [firstName, lastName].filter(Boolean).join(" ") || (typeof data.name === "string" ? data.name.trim() : "") || email || "Website lead";
65720
66172
  const identitySeed = email || `${fullName}:${Date.now()}`;
65721
- const suffix2 = (0, import_node_crypto38.createHash)("sha256").update(identitySeed).digest("hex").slice(0, 12);
66173
+ const suffix2 = (0, import_node_crypto39.createHash)("sha256").update(identitySeed).digest("hex").slice(0, 12);
65722
66174
  const path6 = `Leads/person-${suffix2}`;
65723
66175
  const { key: memoryKey, error: memoryKeyError } = await getOrCreateUserMemoryKey(user);
65724
66176
  const existing = memoryKey ? await memoryCall("getTool", { vault: "People", path: path6 }, memoryKey) : { ok: false, error: memoryKeyError || "memory_credential_unavailable" };
@@ -65817,9 +66269,9 @@ Submitted the published form.
65817
66269
  occurredAt: (/* @__PURE__ */ new Date()).toISOString()
65818
66270
  });
65819
66271
  const match = {
65820
- ...email ? { emailSha256: (0, import_node_crypto38.createHash)("sha256").update(email).digest("hex") } : {},
66272
+ ...email ? { emailSha256: (0, import_node_crypto39.createHash)("sha256").update(email).digest("hex") } : {},
65821
66273
  ...phone ? {
65822
- phoneSha256: (0, import_node_crypto38.createHash)("sha256").update(phone.replace(/\D/g, "")).digest("hex")
66274
+ phoneSha256: (0, import_node_crypto39.createHash)("sha256").update(phone.replace(/\D/g, "")).digest("hex")
65823
66275
  } : {}
65824
66276
  };
65825
66277
  const activationQueued = await queueAnalyticsActivation({
@@ -66247,7 +66699,7 @@ Submitted the published form.
66247
66699
  rejectedCount += 1;
66248
66700
  continue;
66249
66701
  }
66250
- const digest2 = (0, import_node_crypto38.createHash)("sha256").update(
66702
+ const digest2 = (0, import_node_crypto39.createHash)("sha256").update(
66251
66703
  `${parsed.data.sourceSystem}:${externalId || email || phone || `${fullName}:${index}`}`
66252
66704
  ).digest("hex").slice(0, 16);
66253
66705
  const path6 = `Leads/person-${digest2}`;
@@ -66688,13 +67140,13 @@ var init_analytics_delivery = __esm({
66688
67140
 
66689
67141
  // src/api/scheduled-artifact-owner.ts
66690
67142
  function scheduledArtifactOwnerIdForApiKey(apiKey) {
66691
- return (0, import_node_crypto39.createHash)("sha256").update(apiKey).digest("hex").slice(0, 24);
67143
+ return (0, import_node_crypto40.createHash)("sha256").update(apiKey).digest("hex").slice(0, 24);
66692
67144
  }
66693
- var import_node_crypto39;
67145
+ var import_node_crypto40;
66694
67146
  var init_scheduled_artifact_owner = __esm({
66695
67147
  "src/api/scheduled-artifact-owner.ts"() {
66696
67148
  "use strict";
66697
- import_node_crypto39 = require("crypto");
67149
+ import_node_crypto40 = require("crypto");
66698
67150
  }
66699
67151
  });
66700
67152
 
@@ -66751,7 +67203,7 @@ async function ensureScheduledRunViewLinksSchema() {
66751
67203
  schemaReady3 = true;
66752
67204
  }
66753
67205
  function tokenHash2(token4) {
66754
- return (0, import_node_crypto40.createHash)("sha256").update(token4).digest("hex");
67206
+ return (0, import_node_crypto41.createHash)("sha256").update(token4).digest("hex");
66755
67207
  }
66756
67208
  function mapRow(row) {
66757
67209
  return {
@@ -66771,9 +67223,9 @@ function mapRow(row) {
66771
67223
  async function createScheduledRunViewLink(input) {
66772
67224
  await ensureScheduledRunViewLinksSchema();
66773
67225
  const now = input.now ?? /* @__PURE__ */ new Date();
66774
- const token4 = (0, import_node_crypto40.randomBytes)(32).toString("base64url");
67226
+ const token4 = (0, import_node_crypto41.randomBytes)(32).toString("base64url");
66775
67227
  const record = {
66776
- shareId: (0, import_node_crypto40.randomUUID)(),
67228
+ shareId: (0, import_node_crypto41.randomUUID)(),
66777
67229
  ownerId: input.ownerId,
66778
67230
  runId: input.runId,
66779
67231
  artifactId: input.artifactId,
@@ -66836,11 +67288,11 @@ async function revokeScheduledRunViewLink(ownerId, runId, shareId, now = /* @__P
66836
67288
  });
66837
67289
  return result.rowsAffected > 0;
66838
67290
  }
66839
- var import_node_crypto40, schemaReady3;
67291
+ var import_node_crypto41, schemaReady3;
66840
67292
  var init_scheduled_run_view_links = __esm({
66841
67293
  "src/api/scheduled-run-view-links.ts"() {
66842
67294
  "use strict";
66843
- import_node_crypto40 = require("crypto");
67295
+ import_node_crypto41 = require("crypto");
66844
67296
  init_db();
66845
67297
  schemaReady3 = false;
66846
67298
  }
@@ -66906,15 +67358,15 @@ ${section(flags.finalCta && Boolean(finalCta), `<section class="section cta" id=
66906
67358
  html,
66907
67359
  filename: `${input.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "personal-authority"}.html`,
66908
67360
  bytes,
66909
- sha256: (0, import_node_crypto41.createHash)("sha256").update(html).digest("hex"),
67361
+ sha256: (0, import_node_crypto42.createHash)("sha256").update(html).digest("hex"),
66910
67362
  generatedAt: generatedAtIso
66911
67363
  };
66912
67364
  }
66913
- var import_node_crypto41;
67365
+ var import_node_crypto42;
66914
67366
  var init_render2 = __esm({
66915
67367
  "src/personal-authority/render.ts"() {
66916
67368
  "use strict";
66917
- import_node_crypto41 = require("crypto");
67369
+ import_node_crypto42 = require("crypto");
66918
67370
  }
66919
67371
  });
66920
67372
 
@@ -67024,15 +67476,15 @@ body{overflow-x:hidden}.lead-story__body,.lead-support__item,.story-card__body{m
67024
67476
  @media(max-width:620px){.desk-section__grid--panorama,.desk-section__grid--mosaic,.desk-section__grid--tiles{grid-template-columns:1fr}.story-card--panorama{display:block}.story-card--panorama h3,.story-card--mosaic-lead h3{font-size:34px}.story-card--mosaic-lead{grid-column:auto;grid-row:auto}.desk-section__grid--tiles>.story-card:nth-child(3n+2){margin-top:0}}
67025
67477
  </style></head><body data-theme="${escapeHtml9(config.theme)}" id="top" data-scheduled-renderer="newsroom_publisher_v1">${ticker}${masthead}${navigation}<main>${leadGrid}${latest}${sections}${newsletter}${pressRoom}${trustCenter}</main>${trustFooter}</body></html>`;
67026
67478
  const bytes = Buffer.byteLength(html);
67027
- const sha2563 = (0, import_node_crypto42.createHash)("sha256").update(html).digest("hex");
67479
+ const sha2563 = (0, import_node_crypto43.createHash)("sha256").update(html).digest("hex");
67028
67480
  const filename = `${brand.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "newsroom"}-news-site.html`;
67029
67481
  return { html, filename, bytes, sha256: sha2563, generatedAt: generatedAtIso };
67030
67482
  }
67031
- var import_node_crypto42;
67483
+ var import_node_crypto43;
67032
67484
  var init_render3 = __esm({
67033
67485
  "src/newsroom-publisher/render.ts"() {
67034
67486
  "use strict";
67035
- import_node_crypto42 = require("crypto");
67487
+ import_node_crypto43 = require("crypto");
67036
67488
  }
67037
67489
  });
67038
67490
 
@@ -67325,7 +67777,7 @@ function policy4() {
67325
67777
  };
67326
67778
  }
67327
67779
  function runStorageSegment(runId) {
67328
- return /^[a-zA-Z0-9_-]{1,160}$/.test(runId) ? runId : `run-${(0, import_node_crypto43.createHash)("sha256").update(runId).digest("hex").slice(0, 32)}`;
67780
+ return /^[a-zA-Z0-9_-]{1,160}$/.test(runId) ? runId : `run-${(0, import_node_crypto44.createHash)("sha256").update(runId).digest("hex").slice(0, 32)}`;
67329
67781
  }
67330
67782
  async function createScheduledRunArtifact(args) {
67331
67783
  if (args.rendered.bytes > SCHEDULED_RUN_ARTIFACT_MAX_BYTES) {
@@ -67366,12 +67818,12 @@ async function readScheduledRunArtifact(args) {
67366
67818
  if (!window2 || window2.nextOffset !== null || window2.totalBytes > SCHEDULED_RUN_ARTIFACT_MAX_BYTES) return null;
67367
67819
  return window2.text;
67368
67820
  }
67369
- var import_node_crypto43, SCHEDULED_RUN_ARTIFACT_PREFIX, SCHEDULED_RUN_ARTIFACT_DOWNLOAD_TTL_MS, SCHEDULED_RUN_ARTIFACT_MAX_BYTES;
67821
+ var import_node_crypto44, SCHEDULED_RUN_ARTIFACT_PREFIX, SCHEDULED_RUN_ARTIFACT_DOWNLOAD_TTL_MS, SCHEDULED_RUN_ARTIFACT_MAX_BYTES;
67370
67822
  var init_scheduled_run_artifact_store = __esm({
67371
67823
  "src/scheduled-artifacts/scheduled-run-artifact-store.ts"() {
67372
67824
  "use strict";
67373
67825
  init_private_artifacts();
67374
- import_node_crypto43 = require("crypto");
67826
+ import_node_crypto44 = require("crypto");
67375
67827
  SCHEDULED_RUN_ARTIFACT_PREFIX = "scheduled-run-artifacts/";
67376
67828
  SCHEDULED_RUN_ARTIFACT_DOWNLOAD_TTL_MS = 15 * 60 * 1e3;
67377
67829
  SCHEDULED_RUN_ARTIFACT_MAX_BYTES = 2e6;
@@ -67589,7 +68041,7 @@ async function reconcileDiscoveredNangoConnections(identity, discovered) {
67589
68041
  updated_at = excluded.updated_at
67590
68042
  `,
67591
68043
  args: [
67592
- (0, import_node_crypto44.randomUUID)(),
68044
+ (0, import_node_crypto45.randomUUID)(),
67593
68045
  userId,
67594
68046
  connection.providerConfigKey,
67595
68047
  connection.provider,
@@ -67660,7 +68112,7 @@ async function recordServiceConnectionHealth(args) {
67660
68112
  });
67661
68113
  await getDb().execute({
67662
68114
  sql: `INSERT INTO service_connection_health_events (id, connection_id, operational_status, failure_code, retryable, evidence_source) VALUES (?, ?, ?, ?, ?, ?)`,
67663
- args: [(0, import_node_crypto44.randomUUID)(), args.connectionId, args.operationalStatus, args.failureCode ?? null, args.retryable == null ? null : args.retryable ? 1 : 0, args.evidenceSource]
68115
+ args: [(0, import_node_crypto45.randomUUID)(), args.connectionId, args.operationalStatus, args.failureCode ?? null, args.retryable == null ? null : args.retryable ? 1 : 0, args.evidenceSource]
67664
68116
  });
67665
68117
  }
67666
68118
  async function setServiceConnectionActions(identity, connectionId, enabled) {
@@ -67700,7 +68152,7 @@ async function claimServiceConnectionAction(args) {
67700
68152
  if (!connection) throw new Error("service_connection_not_found");
67701
68153
  const inserted = await getDb().execute({
67702
68154
  sql: `INSERT OR IGNORE INTO service_connection_action_audit (id, connection_id, user_id, tool, request_id, status, request_digest) VALUES (?, ?, ?, ?, ?, 'started', ?)`,
67703
- args: [(0, import_node_crypto44.randomUUID)(), connection.id, connection.userId, args.tool, args.requestId, args.requestDigest]
68155
+ args: [(0, import_node_crypto45.randomUUID)(), connection.id, connection.userId, args.tool, args.requestId, args.requestDigest]
67704
68156
  });
67705
68157
  if (Number(inserted.rowsAffected ?? 0) === 1) return { claimed: true };
67706
68158
  const existing = await getDb().execute({
@@ -67725,11 +68177,11 @@ async function claimServiceConnectionAction(args) {
67725
68177
  ...result !== void 0 ? { result } : {}
67726
68178
  };
67727
68179
  }
67728
- var import_node_crypto44, schemaReady4, schemaDb4;
68180
+ var import_node_crypto45, schemaReady4, schemaDb4;
67729
68181
  var init_service_connections = __esm({
67730
68182
  "src/api/service-connections.ts"() {
67731
68183
  "use strict";
67732
- import_node_crypto44 = require("crypto");
68184
+ import_node_crypto45 = require("crypto");
67733
68185
  init_db();
67734
68186
  schemaReady4 = null;
67735
68187
  schemaDb4 = null;
@@ -67743,8 +68195,8 @@ function signingSecret() {
67743
68195
  return secret2;
67744
68196
  }
67745
68197
  function schedulerIntegrationSignature(args) {
67746
- const bodyHash = (0, import_node_crypto45.createHash)("sha256").update(args.body).digest("hex");
67747
- return (0, import_node_crypto45.createHmac)("sha256", args.secret).update(`${args.method.toUpperCase()}
68198
+ const bodyHash = (0, import_node_crypto46.createHash)("sha256").update(args.body).digest("hex");
68199
+ return (0, import_node_crypto46.createHmac)("sha256", args.secret).update(`${args.method.toUpperCase()}
67748
68200
  ${args.path}
67749
68201
  ${args.timestamp}
67750
68202
  ${args.nonce}
@@ -67791,17 +68243,17 @@ async function verifySchedulerIntegrationRequest(request, rawBody) {
67791
68243
  });
67792
68244
  const suppliedBytes = Buffer.from(signature, "hex");
67793
68245
  const expectedBytes = Buffer.from(expected, "hex");
67794
- if (suppliedBytes.length !== expectedBytes.length || !(0, import_node_crypto45.timingSafeEqual)(suppliedBytes, expectedBytes)) {
68246
+ if (suppliedBytes.length !== expectedBytes.length || !(0, import_node_crypto46.timingSafeEqual)(suppliedBytes, expectedBytes)) {
67795
68247
  throw new SchedulerIntegrationAuthError("invalid_signature");
67796
68248
  }
67797
68249
  await claimNonce(nonce, timestampMs);
67798
68250
  return { requestId };
67799
68251
  }
67800
- var import_node_crypto45, MAX_CLOCK_SKEW_MS, SchedulerIntegrationAuthError;
68252
+ var import_node_crypto46, MAX_CLOCK_SKEW_MS, SchedulerIntegrationAuthError;
67801
68253
  var init_scheduler_integration_auth = __esm({
67802
68254
  "src/api/scheduler-integration-auth.ts"() {
67803
68255
  "use strict";
67804
- import_node_crypto45 = require("crypto");
68256
+ import_node_crypto46 = require("crypto");
67805
68257
  init_db();
67806
68258
  init_service_connections();
67807
68259
  MAX_CLOCK_SKEW_MS = 5 * 60 * 1e3;
@@ -68049,7 +68501,7 @@ var init_site_extract_reconciliation = __esm({
68049
68501
 
68050
68502
  // src/api/page-diff.ts
68051
68503
  function sha256Hex(value) {
68052
- return (0, import_node_crypto46.createHash)("sha256").update(value).digest("hex");
68504
+ return (0, import_node_crypto47.createHash)("sha256").update(value).digest("hex");
68053
68505
  }
68054
68506
  function truncateForStorage(value, maxChars = MAX_SNAPSHOT_CONTENT_CHARS) {
68055
68507
  if (value.length <= maxChars) return { value, truncated: false };
@@ -68106,11 +68558,11 @@ function diffPageContent(oldContent, newContent) {
68106
68558
  totalChangedLineCount
68107
68559
  };
68108
68560
  }
68109
- var import_node_crypto46, import_diff, MAX_SNAPSHOT_CONTENT_CHARS, MAX_DIFF_HUNKS, MAX_DIFF_LINES_PER_RESPONSE;
68561
+ var import_node_crypto47, import_diff, MAX_SNAPSHOT_CONTENT_CHARS, MAX_DIFF_HUNKS, MAX_DIFF_LINES_PER_RESPONSE;
68110
68562
  var init_page_diff = __esm({
68111
68563
  "src/api/page-diff.ts"() {
68112
68564
  "use strict";
68113
- import_node_crypto46 = require("crypto");
68565
+ import_node_crypto47 = require("crypto");
68114
68566
  import_diff = require("diff");
68115
68567
  MAX_SNAPSHOT_CONTENT_CHARS = 25e4;
68116
68568
  MAX_DIFF_HUNKS = 200;
@@ -68184,7 +68636,7 @@ var init_scrape_vault_sink = __esm({
68184
68636
 
68185
68637
  // src/api/scrape-image-sink.ts
68186
68638
  function idempotencyKey2(userId, vault, input) {
68187
- return `scrape-image-${(0, import_node_crypto47.createHash)("sha256").update(`${userId}\0${vault}\0${input.sourceKind}\0${input.sourceUrl}\0${input.imageUrl ?? ""}\0${input.imageBase64 ?? ""}`).digest("hex")}`;
68639
+ return `scrape-image-${(0, import_node_crypto48.createHash)("sha256").update(`${userId}\0${vault}\0${input.sourceKind}\0${input.sourceUrl}\0${input.imageUrl ?? ""}\0${input.imageBase64 ?? ""}`).digest("hex")}`;
68188
68640
  }
68189
68641
  async function persistScrapeImagesToMemory(user, inputs, vault) {
68190
68642
  const selected = inputs.slice(0, MAX_IMAGES_PER_SCRAPE);
@@ -68226,11 +68678,11 @@ async function persistScrapeImagesToMemory(user, inputs, vault) {
68226
68678
  assets
68227
68679
  };
68228
68680
  }
68229
- var import_node_crypto47, MAX_IMAGES_PER_SCRAPE;
68681
+ var import_node_crypto48, MAX_IMAGES_PER_SCRAPE;
68230
68682
  var init_scrape_image_sink = __esm({
68231
68683
  "src/api/scrape-image-sink.ts"() {
68232
68684
  "use strict";
68233
- import_node_crypto47 = require("crypto");
68685
+ import_node_crypto48 = require("crypto");
68234
68686
  init_memory();
68235
68687
  MAX_IMAGES_PER_SCRAPE = 25;
68236
68688
  }
@@ -68683,7 +69135,7 @@ function canonicalJson(value) {
68683
69135
  return JSON.stringify(value);
68684
69136
  }
68685
69137
  function sha2562(value) {
68686
- return (0, import_node_crypto48.createHash)("sha256").update(value).digest("hex");
69138
+ return (0, import_node_crypto49.createHash)("sha256").update(value).digest("hex");
68687
69139
  }
68688
69140
  function sensitiveKey(key) {
68689
69141
  const normalized = key.toLowerCase().replace(/[^a-z0-9]/g, "");
@@ -68898,11 +69350,11 @@ async function importServiceConnectionToMemory(identity, input, dependencies) {
68898
69350
  ...!searchReady ? { warning: "The snapshot was stored, but no search chunks were indexed yet." } : {}
68899
69351
  };
68900
69352
  }
68901
- var import_node_crypto48, CONNECTION_MEMORY_IMPORT_MAX_ARGS_BYTES, CONNECTION_MEMORY_IMPORT_MAX_RESULT_BYTES, CONNECTION_MEMORY_IMPORT_MAX_STRING_CHARS, CONNECTION_MEMORY_IMPORT_MAX_DEPTH, ConnectionMemoryImportError;
69353
+ var import_node_crypto49, CONNECTION_MEMORY_IMPORT_MAX_ARGS_BYTES, CONNECTION_MEMORY_IMPORT_MAX_RESULT_BYTES, CONNECTION_MEMORY_IMPORT_MAX_STRING_CHARS, CONNECTION_MEMORY_IMPORT_MAX_DEPTH, ConnectionMemoryImportError;
68902
69354
  var init_connection_memory_import = __esm({
68903
69355
  "src/api/connection-memory-import.ts"() {
68904
69356
  "use strict";
68905
- import_node_crypto48 = require("crypto");
69357
+ import_node_crypto49 = require("crypto");
68906
69358
  init_slugify();
68907
69359
  CONNECTION_MEMORY_IMPORT_MAX_ARGS_BYTES = 64 * 1024;
68908
69360
  CONNECTION_MEMORY_IMPORT_MAX_RESULT_BYTES = 1e6;
@@ -69120,7 +69572,7 @@ function finitePositive(value, fallback) {
69120
69572
  return Number.isFinite(value) && value > 0 ? value : fallback;
69121
69573
  }
69122
69574
  async function collectConnectedDataExport(args) {
69123
- const exportId = (0, import_node_crypto49.randomUUID)();
69575
+ const exportId = (0, import_node_crypto50.randomUUID)();
69124
69576
  const now = args.now ?? Date.now;
69125
69577
  const startedAt = now();
69126
69578
  const budgetMs = finitePositive(CONNECTED_DATA_EXPORT_BUDGET_MS, 24e4);
@@ -69234,11 +69686,11 @@ ${lines.length ? `${lines.join("\n")}
69234
69686
  untrustedContent: true
69235
69687
  };
69236
69688
  }
69237
- var import_node_crypto49, CONNECTED_DATA_INLINE_BUDGET_BYTES, CONNECTED_DATA_MAX_EXPORT_BYTES, CONNECTED_DATA_EXPORT_BUDGET_MS, CONNECTED_DATA_PAGE_START_HEADROOM_MS, CONNECTED_DATA_DATASETS, ConnectedDataExportValidationError;
69689
+ var import_node_crypto50, CONNECTED_DATA_INLINE_BUDGET_BYTES, CONNECTED_DATA_MAX_EXPORT_BYTES, CONNECTED_DATA_EXPORT_BUDGET_MS, CONNECTED_DATA_PAGE_START_HEADROOM_MS, CONNECTED_DATA_DATASETS, ConnectedDataExportValidationError;
69238
69690
  var init_connected_data_export = __esm({
69239
69691
  "src/api/connected-data-export.ts"() {
69240
69692
  "use strict";
69241
- import_node_crypto49 = require("crypto");
69693
+ import_node_crypto50 = require("crypto");
69242
69694
  CONNECTED_DATA_INLINE_BUDGET_BYTES = Number(
69243
69695
  process.env.MCP_SCRAPER_CONNECTED_DATA_INLINE_BUDGET_BYTES ?? 5e4
69244
69696
  );
@@ -69352,7 +69804,7 @@ async function exportSearchConsoleTableData(args) {
69352
69804
  offset += rows.length;
69353
69805
  if (stoppedForBytes || rows.length < limit || offset >= matchedRows) break;
69354
69806
  }
69355
- const exportId = (0, import_node_crypto50.randomUUID)();
69807
+ const exportId = (0, import_node_crypto51.randomUUID)();
69356
69808
  const artifact = await args.writeArtifact({
69357
69809
  ownerId: args.ownerId,
69358
69810
  exportId,
@@ -69374,11 +69826,11 @@ async function exportSearchConsoleTableData(args) {
69374
69826
  warnings
69375
69827
  };
69376
69828
  }
69377
- var import_node_crypto50, SEARCH_CONSOLE_TABLE_EXPORT_MAX_ROWS, SEARCH_CONSOLE_TABLE_EXPORT_PAGE_SIZE, SEARCH_CONSOLE_TABLE_EXPORT_MAX_BYTES, SEARCH_CONSOLE_TABLE_COLUMNS, SearchConsoleTableExportValidationError;
69829
+ var import_node_crypto51, SEARCH_CONSOLE_TABLE_EXPORT_MAX_ROWS, SEARCH_CONSOLE_TABLE_EXPORT_PAGE_SIZE, SEARCH_CONSOLE_TABLE_EXPORT_MAX_BYTES, SEARCH_CONSOLE_TABLE_COLUMNS, SearchConsoleTableExportValidationError;
69378
69830
  var init_search_console_table_export = __esm({
69379
69831
  "src/api/search-console-table-export.ts"() {
69380
69832
  "use strict";
69381
- import_node_crypto50 = require("crypto");
69833
+ import_node_crypto51 = require("crypto");
69382
69834
  SEARCH_CONSOLE_TABLE_EXPORT_MAX_ROWS = 5e4;
69383
69835
  SEARCH_CONSOLE_TABLE_EXPORT_PAGE_SIZE = 2e3;
69384
69836
  SEARCH_CONSOLE_TABLE_EXPORT_MAX_BYTES = 50 * 1024 * 1024;
@@ -70557,7 +71009,7 @@ async function listNangoToolsDirect(identity, connectionId) {
70557
71009
  });
70558
71010
  const readTools = [...policies.values()].filter((policy5) => policy5.classification === "read").map((policy5) => policy5.name);
70559
71011
  const actionTools = [...policies.values()].filter((policy5) => policy5.classification === "action").map((policy5) => policy5.name);
70560
- const revision = (0, import_node_crypto51.createHash)("sha256").update(JSON.stringify(tools.map((tool) => ({ name: tool.name, inputSchema: tool.inputSchema })))).digest("hex");
71012
+ const revision = (0, import_node_crypto52.createHash)("sha256").update(JSON.stringify(tools.map((tool) => ({ name: tool.name, inputSchema: tool.inputSchema })))).digest("hex");
70561
71013
  await updateServiceConnectionTools(connection.id, readTools, actionTools, revision);
70562
71014
  const refreshed = await getOwnedServiceConnection(identity, connection.id);
70563
71015
  return { connection: refreshed ?? { ...connection, readTools, actionTools, toolRevision: revision }, tools };
@@ -70584,8 +71036,8 @@ async function callNangoToolDirect(args) {
70584
71036
  identity: args.identity,
70585
71037
  ratePolicyVersion: CONNECTED_USAGE_RATE_POLICY_VERSION
70586
71038
  });
70587
- const requestId = args.requestId?.trim() || (0, import_node_crypto51.randomUUID)();
70588
- const idempotencyKey3 = `main-nango:${(0, import_node_crypto51.createHash)("sha256").update(args.identity.toLowerCase()).update("\0").update(connection.id).update("\0").update(args.tool).update("\0").update(requestId).digest("hex")}`;
71039
+ const requestId = args.requestId?.trim() || (0, import_node_crypto52.randomUUID)();
71040
+ const idempotencyKey3 = `main-nango:${(0, import_node_crypto52.createHash)("sha256").update(args.identity.toLowerCase()).update("\0").update(connection.id).update("\0").update(args.tool).update("\0").update(requestId).digest("hex")}`;
70589
71041
  const startedAt = /* @__PURE__ */ new Date();
70590
71042
  const started = performance.now();
70591
71043
  let result;
@@ -70610,7 +71062,7 @@ async function callNangoToolDirect(args) {
70610
71062
  toolName: args.tool,
70611
71063
  operationKind: args.operationKind ?? args.classification,
70612
71064
  outcome: providerError ? "error" : "partial",
70613
- requestId: requestId.length <= 200 ? requestId : (0, import_node_crypto51.createHash)("sha256").update(requestId).digest("hex"),
71065
+ requestId: requestId.length <= 200 ? requestId : (0, import_node_crypto52.createHash)("sha256").update(requestId).digest("hex"),
70614
71066
  startedAt: startedAt.toISOString(),
70615
71067
  completedAt: completedAt.toISOString()
70616
71068
  }
@@ -70652,15 +71104,15 @@ async function describeNangoToolDirect(identity, connectionId, toolName) {
70652
71104
  providerContractHash: MAIN_INTEGRATION_CONTRACT_HASH,
70653
71105
  protocolVersion: null,
70654
71106
  schemaSource: "live_tools_list",
70655
- schemaHash: (0, import_node_crypto51.createHash)("sha256").update(JSON.stringify(projected)).digest("hex"),
71107
+ schemaHash: (0, import_node_crypto52.createHash)("sha256").update(JSON.stringify(projected)).digest("hex"),
70656
71108
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
70657
71109
  };
70658
71110
  }
70659
- var import_node_crypto51, import_client13, DEFAULT_NANGO_MCP_URL, NANGO_TIMEOUT_MS, NANGO_CONNECTION_PAGE_SIZE, NANGO_CONNECTION_MAX_PAGES, MAIN_INTEGRATION_CONTRACT_VERSION, MAIN_INTEGRATION_CONTRACT_HASH, MainNangoTransportError;
71111
+ var import_node_crypto52, import_client13, DEFAULT_NANGO_MCP_URL, NANGO_TIMEOUT_MS, NANGO_CONNECTION_PAGE_SIZE, NANGO_CONNECTION_MAX_PAGES, MAIN_INTEGRATION_CONTRACT_VERSION, MAIN_INTEGRATION_CONTRACT_HASH, MainNangoTransportError;
70660
71112
  var init_main_nango_transport = __esm({
70661
71113
  "src/api/main-nango-transport.ts"() {
70662
71114
  "use strict";
70663
- import_node_crypto51 = require("crypto");
71115
+ import_node_crypto52 = require("crypto");
70664
71116
  import_client13 = require("@modelcontextprotocol/client");
70665
71117
  init_service_connections();
70666
71118
  init_connected_usage_billing();
@@ -71284,8 +71736,8 @@ async function setScheduleConnectionActionsEnabled(identity, connectionId, enabl
71284
71736
  return data.connection.actionsEnabled === true;
71285
71737
  }
71286
71738
  async function callScheduleConnectionAction(identity, connectionId, input, tool, idempotencyKey3) {
71287
- const requestId = `main-connected-action:${(0, import_node_crypto52.createHash)("sha256").update(identity).update("\0").update(idempotencyKey3?.trim() || (0, import_node_crypto52.randomUUID)()).digest("hex")}`;
71288
- const requestDigest = (0, import_node_crypto52.createHash)("sha256").update(connectionId).update("\0").update(tool?.trim() ?? "").update("\0").update(canonicalJson2(input)).digest("hex");
71739
+ const requestId = `main-connected-action:${(0, import_node_crypto53.createHash)("sha256").update(identity).update("\0").update(idempotencyKey3?.trim() || (0, import_node_crypto53.randomUUID)()).digest("hex")}`;
71740
+ const requestDigest = (0, import_node_crypto53.createHash)("sha256").update(connectionId).update("\0").update(tool?.trim() ?? "").update("\0").update(canonicalJson2(input)).digest("hex");
71289
71741
  if (mainOwnsIntegrations()) {
71290
71742
  const selectedTool = tool?.trim();
71291
71743
  if (!selectedTool) throw new NangoControlError("An action tool is required.", 400, "invalid_request", false);
@@ -71436,7 +71888,7 @@ function canonicalJson2(value) {
71436
71888
  return JSON.stringify(value);
71437
71889
  }
71438
71890
  function projectedToolSchemaHash(tool) {
71439
- return (0, import_node_crypto52.createHash)("sha256").update(canonicalJson2(tool)).digest("hex");
71891
+ return (0, import_node_crypto53.createHash)("sha256").update(canonicalJson2(tool)).digest("hex");
71440
71892
  }
71441
71893
  async function describeNangoTool(identity, connectionId, tool, fresh) {
71442
71894
  if (mainOwnsIntegrations()) {
@@ -71713,11 +72165,11 @@ async function callMainOwnedExportPage(identity, input) {
71713
72165
  untrustedContent: true
71714
72166
  };
71715
72167
  }
71716
- var import_node_crypto52, DEFAULT_NANGO_CONTROL_URL, DISABLED_NANGO_TOOLS, CONNECTION_SYNC_REQUIRED_TOOLS, CONNECTION_SYNC_OPTIONAL_TOOLS, NangoControlError, ScheduleConnectionValidationError, SAFE_CONTROL_ERROR_CODES, FIXED_CONTROL_ERROR_MESSAGES, CONTROL_ERROR_CODE_ALIASES;
72168
+ var import_node_crypto53, DEFAULT_NANGO_CONTROL_URL, DISABLED_NANGO_TOOLS, CONNECTION_SYNC_REQUIRED_TOOLS, CONNECTION_SYNC_OPTIONAL_TOOLS, NangoControlError, ScheduleConnectionValidationError, SAFE_CONTROL_ERROR_CODES, FIXED_CONTROL_ERROR_MESSAGES, CONTROL_ERROR_CODE_ALIASES;
71717
72169
  var init_nango_control = __esm({
71718
72170
  "src/api/nango-control.ts"() {
71719
72171
  "use strict";
71720
- import_node_crypto52 = require("crypto");
72172
+ import_node_crypto53 = require("crypto");
71721
72173
  init_connected_data_export();
71722
72174
  init_slack_connected_data_export();
71723
72175
  init_main_nango_transport();
@@ -72073,7 +72525,7 @@ async function callResendRead(identity, connectionId, tool, args) {
72073
72525
  return isRecord5(data) ? data.result ?? data : data;
72074
72526
  }
72075
72527
  async function callResendAction(identity, connectionId, tool, input, idempotencyKey3) {
72076
- const requestId = `main-resend-action:${(0, import_node_crypto53.createHash)("sha256").update(identity).update("\0").update(idempotencyKey3.trim()).digest("hex")}`;
72528
+ const requestId = `main-resend-action:${(0, import_node_crypto54.createHash)("sha256").update(identity).update("\0").update(idempotencyKey3.trim()).digest("hex")}`;
72077
72529
  const body = await controlRequest2("/api/internal/resend/actions/call", {
72078
72530
  method: "POST",
72079
72531
  headers: { "x-request-id": requestId },
@@ -72138,12 +72590,12 @@ async function callResendExportPage(identity, input) {
72138
72590
  untrustedContent: true
72139
72591
  };
72140
72592
  }
72141
- var import_node_crypto53, DEFAULT_CONNECTION_CONTROL_URL, RESEND_PROVIDER_CONFIG_KEY, RESEND_LOGO_URL, RESEND_DOCS_URL, RESEND_ADMIN_BLOCKED_TOOLS, RESEND_CONNECTION_SYNC_REQUIRED_TOOLS, ResendControlError;
72593
+ var import_node_crypto54, DEFAULT_CONNECTION_CONTROL_URL, RESEND_PROVIDER_CONFIG_KEY, RESEND_LOGO_URL, RESEND_DOCS_URL, RESEND_ADMIN_BLOCKED_TOOLS, RESEND_CONNECTION_SYNC_REQUIRED_TOOLS, ResendControlError;
72142
72594
  var init_resend_control = __esm({
72143
72595
  "src/api/resend-control.ts"() {
72144
72596
  "use strict";
72145
72597
  init_connected_data_export();
72146
- import_node_crypto53 = require("crypto");
72598
+ import_node_crypto54 = require("crypto");
72147
72599
  DEFAULT_CONNECTION_CONTROL_URL = "https://mcp-scraper-scheduler.vercel.app";
72148
72600
  RESEND_PROVIDER_CONFIG_KEY = "resend";
72149
72601
  RESEND_LOGO_URL = "https://cdn.resend.com/brand/resend-icon-black.svg";
@@ -72661,7 +73113,7 @@ async function chargeTierChangeNow(stripeClient, subscriptionId, customerId) {
72661
73113
  return { ok: false, amountDue: 0, error: err instanceof Error ? err.message : "Unable to charge the plan change immediately." };
72662
73114
  }
72663
73115
  }
72664
- var import_resend3, import_node_crypto54, import_hono36, import_hono37, import_factory8, import_cookie2, import_stripe2, secureCookies2, isProduction2, sessionCookieOptions2, requireAllowedOrigin, auth4, sessionAuth, requireIntegrationsTier, requirePaidSchedulingTier, app, deploymentProfile, STRIPE_API_VERSION, SYNC_HARVEST_TIMEOUT_OVERRIDE_MS;
73116
+ var import_resend3, import_node_crypto55, import_hono36, import_hono37, import_factory8, import_cookie2, import_stripe2, secureCookies2, isProduction2, sessionCookieOptions2, requireAllowedOrigin, auth4, sessionAuth, requireIntegrationsTier, requirePaidSchedulingTier, app, deploymentProfile, STRIPE_API_VERSION, SYNC_HARVEST_TIMEOUT_OVERRIDE_MS;
72665
73117
  var init_server = __esm({
72666
73118
  "src/api/server.ts"() {
72667
73119
  "use strict";
@@ -72674,7 +73126,7 @@ var init_server = __esm({
72674
73126
  init_og();
72675
73127
  import_resend3 = require("resend");
72676
73128
  init_url_utils();
72677
- import_node_crypto54 = require("crypto");
73129
+ import_node_crypto55 = require("crypto");
72678
73130
  init_kpo_extractor();
72679
73131
  init_screenshot();
72680
73132
  init_media_extractor();
@@ -74209,7 +74661,7 @@ var init_server = __esm({
74209
74661
  if (!harvestOk) return c.json(insufficientBalanceResponse(harvestBal, harvestCost), 402);
74210
74662
  jobId2 = await createJob(user.id, options.query, { ...options, billingHoldMc: harvestCost }, body.callback_url);
74211
74663
  } else {
74212
- jobId2 = (0, import_node_crypto54.randomUUID)();
74664
+ jobId2 = (0, import_node_crypto55.randomUUID)();
74213
74665
  const billingDebitKey = `paa-harvest:${jobId2}:hold`;
74214
74666
  const description = `PAA harvest: ${options.query}`.slice(0, 500);
74215
74667
  const hold = await debitMcIdempotent(