@sonordev/site-kit 7.1.1 → 7.2.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.
- package/AGENTS.md +3 -3
- package/CHANGELOG.md +68 -3426
- package/README.md +9 -8
- package/agent-manifest.json +12 -4
- package/dist/{AnalyticsProvider-3MI5RCTL.js → AnalyticsProvider-SLFFBRPE.js} +4 -4
- package/dist/{ArticleViewTracker-CMBSJR3N.js → ArticleViewTracker-TM5AMGN2.js} +3 -3
- package/dist/{BlocksPopup-X3OAAK2L.js → BlocksPopup-YJNJIVPO.js} +5 -5
- package/dist/ChatWidget-XKOSH66S.js +17 -0
- package/dist/{FileField-QRSEGO6D.js → FileField-CI4UL5SH.js} +3 -3
- package/dist/{FormSpotlight-XKV7VTN4.js → FormSpotlight-F2AAEGBN.js} +20 -6
- package/dist/{FormStage-C3YGYAUZ.js → FormStage-BI5R5CNC.js} +27 -7
- package/dist/ManagedForm-G6COGHXL.js +16 -0
- package/dist/{ManagedNewsletterForm-LPIKGJF4.js → ManagedNewsletterForm-BO3WCGXX.js} +7 -5
- package/dist/{SignalCore-ICXXZBYI.js → SignalCore-ZA6WHKBR.js} +3 -3
- package/dist/SiteChat-YJADDTKG.js +5 -0
- package/dist/{SiteDesignReporter-A7MS2CIP.js → SiteDesignReporter-5YAW36AQ.js} +5 -5
- package/dist/SitePopups-ST5PMKZE.js +10 -0
- package/dist/SitemapSync-RJTEBINX.js +8 -0
- package/dist/SitemapSync.d.ts +1 -1
- package/dist/_client/booking-widget.js +5 -5
- package/dist/_client/testimonial-section.d.ts +1 -1
- package/dist/affiliates/api.d.ts +1 -1
- package/dist/affiliates/index.js +3 -3
- package/dist/analytics/AnalyticsProvider.d.ts +1 -1
- package/dist/analytics/index.js +4 -4
- package/dist/analytics/send-gate.d.ts +13 -26
- package/dist/articles/Article.d.ts +1 -1
- package/dist/articles/ArticleList.d.ts +1 -1
- package/dist/articles/ClusterLandingPage.d.ts +2 -2
- package/dist/articles/PublicationLayout.d.ts +1 -1
- package/dist/articles/PublicationSidebar.d.ts +1 -1
- package/dist/articles/RelatedPosts.d.ts +1 -1
- package/dist/articles/author-schema.d.ts +1 -1
- package/dist/articles/excerpt.d.ts +3 -4
- package/dist/articles/index.d.ts +2 -2
- package/dist/articles/index.js +2 -2
- package/dist/articles/news-sitemap.d.ts +1 -1
- package/dist/articles/processArticleHtml.d.ts +1 -1
- package/dist/articles/server-core.d.ts +4 -4
- package/dist/articles/server-ui.js +3 -2
- package/dist/articles/server.d.ts +4 -4
- package/dist/articles/server.js +2 -1
- package/dist/articles/types.d.ts +1 -1
- package/dist/{engage → chat}/ChatWidget.d.ts +8 -7
- package/dist/{engage → chat}/EchoUiActions.d.ts +4 -4
- package/dist/chat/SiteChat.d.ts +25 -0
- package/dist/{engage → chat}/brand-color.d.ts +2 -2
- package/dist/{engage → chat}/chat-messages.d.ts +1 -1
- package/dist/{engage → chat}/echo-config.d.ts +1 -1
- package/dist/chat/index.d.ts +10 -6
- package/dist/chat/index.js +14 -8
- package/dist/{engage → chat}/launcher-placement.d.ts +1 -7
- package/dist/{engage → chat}/socket-loader.d.ts +2 -2
- package/dist/chat/types.d.ts +136 -0
- package/dist/chunk-27FISYK4.js +4 -0
- package/dist/{chunk-QPEEKFCA.js → chunk-4NTBQNHA.js} +249 -80
- package/dist/{chunk-RK7GF7PQ.js → chunk-5V2V5C3Y.js} +2 -4
- package/dist/{chunk-ICFRH2ED.js → chunk-5YCEMV2L.js} +1 -1
- package/dist/{chunk-V4HUSHZO.js → chunk-64DKGVEI.js} +41 -7
- package/dist/{chunk-GLHQ3LRO.js → chunk-6U3VLV2C.js} +1 -1
- package/dist/{chunk-ZETJTCMV.js → chunk-BC4Y3S3D.js} +1 -1
- package/dist/{chunk-JSZN6LDZ.js → chunk-BF7TZYC3.js} +38 -31
- package/dist/{chunk-EFPS56JA.js → chunk-BKY2ZNM7.js} +1 -1
- package/dist/{chunk-AQSNPZY4.js → chunk-C2FZBUSS.js} +80 -1
- package/dist/{chunk-H42PZKVC.js → chunk-CF5QNFYU.js} +2 -2
- package/dist/{chunk-JC7KXNNM.js → chunk-D5DCBD4Y.js} +2 -2
- package/dist/{chunk-PXZ7LAOY.js → chunk-D6ZC7XKZ.js} +2 -2
- package/dist/chunk-EJVQJCG5.js +370 -0
- package/dist/{chunk-6OL23QYD.js → chunk-F24FNCTK.js} +1 -1
- package/dist/{chunk-NEKEH4CK.js → chunk-FR6BYFPC.js} +53 -21
- package/dist/{chunk-KOPVJQ2P.js → chunk-GEXT7BTE.js} +1 -1
- package/dist/{chunk-ZAWANWUS.js → chunk-GGORNBSC.js} +18 -6
- package/dist/{chunk-DUQMSNF2.js → chunk-HGFAEDG3.js} +1 -1
- package/dist/chunk-HODO5BX5.js +28 -0
- package/dist/chunk-HW7B43E5.js +14 -0
- package/dist/{chunk-EQBZ24VH.js → chunk-IAM3D3RL.js} +43 -24
- package/dist/{chunk-ODADQM6Z.js → chunk-JJ3DELUL.js} +2 -2
- package/dist/{chunk-542MIHNP.js → chunk-JMLK6MH7.js} +1 -1
- package/dist/{chunk-7FWA3I6A.js → chunk-JWTQS5F5.js} +1 -1
- package/dist/{chunk-OUNRFXDC.js → chunk-K4ZHAURD.js} +1 -1
- package/dist/chunk-NV72HZ4W.js +45 -0
- package/dist/{chunk-4Y5FWDPM.js → chunk-NZ4RXN3G.js} +55 -7
- package/dist/chunk-OWZ7ATLZ.js +187 -0
- package/dist/{chunk-TXBAOEKG.js → chunk-PKGN32AU.js} +5 -4
- package/dist/chunk-Q6E4OPGG.js +40 -0
- package/dist/{chunk-J4D6ZXRW.js → chunk-QL6XNPSD.js} +3 -3
- package/dist/{chunk-HAG4YIZY.js → chunk-R46IQIGK.js} +6 -6
- package/dist/{chunk-R3VKF43H.js → chunk-RPZ7OQGD.js} +1 -1
- package/dist/{chunk-Q3S26EQA.js → chunk-S54ECQGY.js} +1 -1
- package/dist/{chunk-JIL5VY2R.js → chunk-VHKEF5ZB.js} +1 -1
- package/dist/{chunk-ILAW3XKD.js → chunk-VO3JYRT5.js} +43 -29
- package/dist/chunk-VWWITFWM.js +300 -0
- package/dist/{chunk-OPRBF7VE.js → chunk-ZTLMPUO6.js} +3 -2
- package/dist/client/index.js +3 -3
- package/dist/cms/CmsPreview.d.ts +2 -2
- package/dist/cms/index.d.ts +3 -3
- package/dist/cms/server-api.d.ts +1 -1
- package/dist/cms/types.d.ts +1 -1
- package/dist/commerce/EventCheckout.d.ts +1 -1
- package/dist/commerce/EventsAgenda.d.ts +3 -3
- package/dist/commerce/api.d.ts +1 -1
- package/dist/commerce/index.js +4 -4
- package/dist/commerce/server.d.ts +3 -4
- package/dist/contracts/color.d.ts +1 -1
- package/dist/contracts/entries.d.ts +1 -1
- package/dist/contracts/error-page.d.ts +183 -0
- package/dist/contracts/fleet.d.ts +9 -9
- package/dist/contracts/forms.d.ts +4 -10
- package/dist/contracts/llms.d.ts +2 -1
- package/dist/contracts/portfolio.d.ts +11 -15
- package/dist/contracts/proposal-sitemap.d.ts +130 -0
- package/dist/contracts/schema-placeholders.d.ts +87 -0
- package/dist/contracts/seo-meta.d.ts +11 -12
- package/dist/contracts/seo-pages.d.ts +12 -18
- package/dist/contracts/site-cache.d.ts +4 -4
- package/dist/contracts/sites-normalize.d.ts +2 -4
- package/dist/contracts/sites.d.ts +3 -5
- package/dist/contracts/slot-content.d.ts +2 -2
- package/dist/contracts/slots.d.ts +6 -6
- package/dist/contracts/voice.d.ts +56 -0
- package/dist/contracts/website.d.ts +2 -2
- package/dist/engage/EngageWidget.d.ts +13 -12
- package/dist/engage/index.d.ts +10 -9
- package/dist/engage/index.js +31 -35
- package/dist/engage/types.d.ts +19 -244
- package/dist/fleet/FleetHeartbeat.d.ts +2 -2
- package/dist/fleet/index.js +4 -4
- package/dist/forms/FormEnhancer.d.ts +25 -12
- package/dist/forms/FormSpotlight.d.ts +2 -2
- package/dist/forms/ManagedForm.d.ts +1 -1
- package/dist/forms/ServerForm.d.ts +11 -10
- package/dist/forms/StaticForm.d.ts +4 -2
- package/dist/forms/field-autocomplete.d.ts +28 -0
- package/dist/forms/field-interactions.d.ts +2 -2
- package/dist/forms/form-dom-values.d.ts +42 -0
- package/dist/forms/form-loaded-at.d.ts +2 -2
- package/dist/forms/formsApi.d.ts +2 -2
- package/dist/forms/index.d.ts +1 -1
- package/dist/forms/index.js +11 -9
- package/dist/forms/server.d.ts +1 -1
- package/dist/forms/server.js +6 -4
- package/dist/forms/static.js +3 -2
- package/dist/forms/submitForm.d.ts +9 -2
- package/dist/forms/types.d.ts +44 -5
- package/dist/forms/useForm.d.ts +21 -4
- package/dist/forms/webmcp.d.ts +38 -0
- package/dist/images/ManagedFavicon.d.ts +1 -1
- package/dist/images/ManagedImage.d.ts +4 -4
- package/dist/images/api.d.ts +1 -1
- package/dist/images/index.d.ts +2 -2
- package/dist/images/index.js +4 -4
- package/dist/index.d.ts +4 -1
- package/dist/index.js +1 -1
- package/dist/landing/contract.d.ts +3 -4
- package/dist/layout/SiteKitClientProviders.d.ts +4 -4
- package/dist/layout/SiteKitLayout.d.ts +11 -11
- package/dist/layout/client.d.ts +4 -4
- package/dist/layout/client.js +7 -7
- package/dist/layout/index.js +8 -8
- package/dist/layout/types.d.ts +7 -6
- package/dist/llms/SpeakableSchema.d.ts +2 -2
- package/dist/llms/agent-access.d.ts +2 -2
- package/dist/llms/aiRobots.d.ts +4 -4
- package/dist/llms/api.d.ts +2 -2
- package/dist/llms/contract.js +1 -1
- package/dist/llms/generateLLMsTxt.d.ts +1 -1
- package/dist/llms/index.js +6 -6
- package/dist/llms/links.d.ts +1 -1
- package/dist/llms/revalidate.d.ts +1 -1
- package/dist/llms/seo-revalidate.d.ts +2 -3
- package/dist/llms/types.d.ts +6 -6
- package/dist/llms/writeLLMsTxt.d.ts +10 -10
- package/dist/manifest/index.d.ts +8 -8
- package/dist/maps/index.js +3 -3
- package/dist/mcp/WebMcpTools.d.ts +1 -1
- package/dist/mcp/index.js +2 -14
- package/dist/mcp/report.d.ts +2 -2
- package/dist/mcp/serverCard.d.ts +1 -1
- package/dist/mcp/sonor.d.ts +5 -6
- package/dist/mcp/sonor.js +14 -11
- package/dist/mcp/transport.d.ts +1 -2
- package/dist/mcp/types.d.ts +4 -5
- package/dist/motion/engine.d.ts +2 -3
- package/dist/motion/failsafe.d.ts +1 -2
- package/dist/motion/gsap.d.ts +2 -2
- package/dist/motion/three.d.ts +1 -1
- package/dist/og/config.d.ts +4 -4
- package/dist/og/contrast.d.ts +2 -2
- package/dist/og/pages.d.ts +5 -5
- package/dist/og/route-fit.d.ts +2 -2
- package/dist/og/route.d.ts +1 -2
- package/dist/og/template.d.ts +1 -1
- package/dist/proxy/index.d.ts +2 -2
- package/dist/proxy/securityHeaders.d.ts +10 -12
- package/dist/redirects/index.d.ts +7 -7
- package/dist/reputation/TestimonialSection.d.ts +1 -1
- package/dist/reputation/api.d.ts +1 -1
- package/dist/revalidate/index.js +2 -2
- package/dist/robots/index.d.ts +5 -5
- package/dist/robots/indexnow.d.ts +2 -3
- package/dist/seo/ManagedScripts.d.ts +2 -2
- package/dist/seo/client.js +4 -4
- package/dist/seo/getManagedMetadata.d.ts +1 -1
- package/dist/seo/groundingSchema.d.ts +2 -2
- package/dist/seo/index.js +15 -8
- package/dist/seo/llms/contract.js +1 -1
- package/dist/seo/llms.js +6 -6
- package/dist/seo/register-sitemap-cli-impl.d.ts +1 -1
- package/dist/seo/register-sitemap-cli.d.ts +1 -1
- package/dist/seo/register-sitemap-cli.js +2 -2
- package/dist/seo/schema-filter.d.ts +5 -6
- package/dist/seo/server-api.d.ts +1 -1
- package/dist/seo/sitemap.js +4 -4
- package/dist/seo/types.d.ts +4 -4
- package/dist/seo/withManagedMetadata.d.ts +4 -4
- package/dist/server/index.js +2 -2
- package/dist/server/mint-site-token.d.ts +1 -2
- package/dist/server/server-fetch.d.ts +5 -5
- package/dist/shared/build-entries.d.ts +4 -4
- package/dist/shared/dialog.d.ts +27 -0
- package/dist/shared/frame.d.ts +8 -9
- package/dist/shared/fresh-fetch.d.ts +1 -2
- package/dist/shared/identity.d.ts +1 -1
- package/dist/shared/layers.d.ts +7 -0
- package/dist/shared/mid-form.d.ts +53 -0
- package/dist/shared/next-files.d.ts +1 -1
- package/dist/shared/publishCredential.d.ts +1 -1
- package/dist/shared/reporting-gate.d.ts +1 -1
- package/dist/shared/uuid.d.ts +1 -2
- package/dist/shared/version.d.ts +1 -1
- package/dist/shared/visual-viewport-gap.d.ts +3 -3
- package/dist/signal/index.js +2 -2
- package/dist/signal/types.d.ts +1 -1
- package/dist/site-config/index.d.ts +2 -2
- package/dist/sitemap/index.d.ts +13 -13
- package/dist/sitemap/index.js +4 -4
- package/dist/sitemap/shared.d.ts +3 -3
- package/dist/sites/site-param.d.ts +2 -2
- package/dist/slots/ManagedRichText.d.ts +1 -1
- package/dist/slots/ManagedSlot.d.ts +1 -1
- package/dist/slots/index.d.ts +1 -3
- package/dist/{socket-loader-R24ZSRSQ.js → socket-loader-CGIPEG74.js} +1 -1
- package/dist/sync/index.js +5 -5
- package/dist/types.d.ts +4 -2
- package/dist/website/BlocksPopup.d.ts +1 -1
- package/dist/website/PopupBlocks.d.ts +8 -6
- package/dist/website/SitePopups.d.ts +25 -0
- package/dist/website/images.js +4 -4
- package/dist/website/index.js +6 -6
- package/dist/website/popup-rules.d.ts +46 -0
- package/dist/website/popup-types.d.ts +113 -0
- package/dist/website/popups.d.ts +2 -6
- package/dist/website/popups.js +6 -14
- package/dist/{writeLLMsTxt-QR23OQUE.js → writeLLMsTxt-OV24LQVL.js} +3 -3
- package/docs/MIGRATING-TO-7.md +50 -22
- package/docs.json +2 -1
- package/package.json +2 -2
- package/src/admin-auth/README.md +3 -3
- package/src/analytics/README.md +9 -11
- package/src/articles/README.md +10 -7
- package/src/{engage → chat}/README.md +63 -62
- package/src/cta-bar/README.md +11 -11
- package/src/forms/README.md +60 -12
- package/src/layout/README.md +8 -5
- package/src/llms/README.md +3 -3
- package/src/mcp/README.md +7 -7
- package/src/motion/README.md +1 -1
- package/src/og/README.md +26 -27
- package/src/proxy/README.md +14 -14
- package/src/seo/README.md +4 -2
- package/src/slots/README.md +1 -1
- package/src/sync/README.md +10 -0
- package/src/website/README.md +133 -0
- package/dist/ChatWidget-JMFBXJ75.js +0 -15
- package/dist/EngageWidget-A3QKZ3SU.js +0 -11
- package/dist/ManagedForm-2GSSDJPP.js +0 -14
- package/dist/SitemapSync-4U654SEA.js +0 -8
- package/dist/chunk-B73QPZPH.js +0 -837
- package/dist/chunk-NDF4A5JM.js +0 -37
- package/dist/chunk-RTMMHTEQ.js +0 -100
- package/dist/engage/DesignRenderer.d.ts +0 -57
- package/dist/engage/element-rules.d.ts +0 -38
|
@@ -10,9 +10,8 @@
|
|
|
10
10
|
*
|
|
11
11
|
* The AI article pipeline stores content as JSON sections
|
|
12
12
|
* (`{"heading": "## ...", "content": "## ...\n\nIf you're asking **how**..."}`)
|
|
13
|
-
* and that value
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* and cap at a sentence boundary.
|
|
13
|
+
* and that value can ship verbatim into <meta name="description">, leaving a
|
|
14
|
+
* SERP snippet of raw JSON with markdown asterisks and literal \n. Parse the
|
|
15
|
+
* sections out, strip markdown, and cap at a sentence boundary.
|
|
17
16
|
*/
|
|
18
17
|
export declare function sanitizeExcerpt(raw: string | undefined | null, maxLength?: number): string;
|
package/dist/articles/index.d.ts
CHANGED
|
@@ -62,8 +62,8 @@ export type { ClusterNavigationProps } from './ClusterNavigation';
|
|
|
62
62
|
* `CLIENT_ENTRIES`, `src/shared/build-entries.ts`), so every module it reaches
|
|
63
63
|
* is client code by declaration. `ClusterLandingPage` is an async component that
|
|
64
64
|
* awaits `getTopicCluster` from `./server-core`, so exporting it from here put
|
|
65
|
-
* that module's `x-api-key` fetch into the browser bundle
|
|
66
|
-
*
|
|
65
|
+
* that module's `x-api-key` fetch into the browser bundle (confirmed in a real
|
|
66
|
+
* site's build, in `.next/static/chunks/`). It also could never have
|
|
67
67
|
* worked as a client component: async components are server-only.
|
|
68
68
|
*
|
|
69
69
|
* The type stays — `export type` is erased at build time and reaches no runtime
|
package/dist/articles/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { NewsletterShell } from '../chunk-SC4MZGWZ.js';
|
|
3
2
|
export { ArticleFAQ } from '../chunk-GKGSXUVQ.js';
|
|
3
|
+
import { NewsletterShell } from '../chunk-SC4MZGWZ.js';
|
|
4
4
|
import { getAuthorSocialLinks, readingTimeMinutes } from '../chunk-FV2VD7WM.js';
|
|
5
5
|
export { ClusterNavigation, ServiceCallout, ServiceCallouts } from '../chunk-FV2VD7WM.js';
|
|
6
6
|
import '../chunk-GYF2ULVO.js';
|
|
@@ -15,7 +15,7 @@ import '../chunk-PKBMQBKP.js';
|
|
|
15
15
|
import React, { useState, Suspense, useEffect } from 'react';
|
|
16
16
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
17
17
|
|
|
18
|
-
var ManagedNewsletterForm = React.lazy(() => import('../ManagedNewsletterForm-
|
|
18
|
+
var ManagedNewsletterForm = React.lazy(() => import('../ManagedNewsletterForm-BO3WCGXX.js'));
|
|
19
19
|
function NewsletterWidget({
|
|
20
20
|
title = "Subscribe to Our Newsletter",
|
|
21
21
|
description = "Get the latest posts delivered straight to your inbox.",
|
|
@@ -26,7 +26,7 @@ export interface NewsSitemapPost extends ArticleRoutePost {
|
|
|
26
26
|
}
|
|
27
27
|
export interface NewsSitemapOptions extends PublicationRoutingOptions {
|
|
28
28
|
siteUrl: string;
|
|
29
|
-
/** The publication name, exactly as it appears on the articles (e.g. "The
|
|
29
|
+
/** The publication name, exactly as it appears on the articles (e.g. "The Journal by Example Co."). */
|
|
30
30
|
publicationName: string;
|
|
31
31
|
/** ISO 639 language code. Defaults to "en". */
|
|
32
32
|
language?: string;
|
|
@@ -74,8 +74,8 @@ export declare function getArticle(slug: string, options?: {
|
|
|
74
74
|
*
|
|
75
75
|
* `getArticle` returns null for a mistyped or deleted slug, and the page
|
|
76
76
|
* used to carry on rendering a "not found" message with HTTP 200 and an
|
|
77
|
-
* indexable title: a soft 404 on every bad post URL
|
|
78
|
-
*
|
|
77
|
+
* indexable title: a soft 404 on every bad post URL. This calls Next's
|
|
78
|
+
* `notFound()` instead, so the
|
|
79
79
|
* route answers 404 with `noindex`.
|
|
80
80
|
*
|
|
81
81
|
* Call it from `generateMetadata` (or the page) before rendering `Article`:
|
|
@@ -293,7 +293,7 @@ export declare function generateRssFeed(options: RssFeedOptions): Promise<string
|
|
|
293
293
|
export declare function generateAtomFeed(options: RssFeedOptions): Promise<string>;
|
|
294
294
|
/**
|
|
295
295
|
* Fetch all active topic clusters for the project.
|
|
296
|
-
* Uses the real cluster data from
|
|
296
|
+
* Uses the real cluster data from Sonor API (not heuristic-based).
|
|
297
297
|
*/
|
|
298
298
|
export declare function getTopicClusters(options?: {
|
|
299
299
|
site?: string;
|
|
@@ -449,7 +449,7 @@ export declare function generateAuthorPageMetadata(author: ArticleAuthor, option
|
|
|
449
449
|
* keeps its existing public API.
|
|
450
450
|
*/
|
|
451
451
|
export { authorEntityId, generateArticleAuthorNode, generateAuthorPersonSchema, generateAuthorSchema, withArticleAuthorIdentity, type AuthorSchemaOptions, } from './author-schema';
|
|
452
|
-
/**
|
|
452
|
+
/** Sonor article document shape (alias of `Article` from `./types`) */
|
|
453
453
|
export type { Article as ArticleRecord } from './types';
|
|
454
454
|
export { articleCategorySlug, createPublicationRoutes, resolveArticleUrl, resolvePublicationUrl } from './routes';
|
|
455
455
|
export type { ArticleRoutePost, PublicationRoutingOptions } from './routes';
|
|
@@ -2,12 +2,13 @@ import { readingTimeMinutes, ServiceCallouts, ClusterNavigation, getAuthorSocial
|
|
|
2
2
|
export { ClusterNavigation } from '../chunk-FV2VD7WM.js';
|
|
3
3
|
import { widgetStyle, widgetTitleStyle } from '../chunk-GYF2ULVO.js';
|
|
4
4
|
import { resolvePublicationSiteUrl, addExternalLinkTargets } from '../chunk-L5UOHS6E.js';
|
|
5
|
-
import { fetchArticleBySlug, fetchRelatedArticles, fetchArticleCategories, getTopicCluster } from '../chunk-
|
|
5
|
+
import { fetchArticleBySlug, fetchRelatedArticles, fetchArticleCategories, getTopicCluster } from '../chunk-PKGN32AU.js';
|
|
6
6
|
export { articleTableCss, wrapArticleTables } from '../chunk-Y3INC4QJ.js';
|
|
7
7
|
import { resolveArticleArtwork, articleArtworkImageStyle } from '../chunk-QXMIKDOL.js';
|
|
8
8
|
export { resolveArticleArtwork } from '../chunk-QXMIKDOL.js';
|
|
9
9
|
import { createPublicationRoutes, articleCategorySlug } from '../chunk-WMVK77ND.js';
|
|
10
10
|
export { articleCategorySlug, createPublicationRoutes, resolveArticleUrl, resolvePublicationUrl } from '../chunk-WMVK77ND.js';
|
|
11
|
+
import '../chunk-VWWITFWM.js';
|
|
11
12
|
import { withSiteParam } from '../chunk-MJP63SSS.js';
|
|
12
13
|
import '../chunk-X6F6SO4S.js';
|
|
13
14
|
import '../chunk-MH2DSGC6.js';
|
|
@@ -132,7 +133,7 @@ async function Article({
|
|
|
132
133
|
...item,
|
|
133
134
|
answer: addExternalLinkTargets(item.answer || "", siteUrlResolved)
|
|
134
135
|
})) ?? faqRaw;
|
|
135
|
-
const { ArticleViewTracker } = await import('../ArticleViewTracker-
|
|
136
|
+
const { ArticleViewTracker } = await import('../ArticleViewTracker-TM5AMGN2.js');
|
|
136
137
|
if (children) {
|
|
137
138
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
138
139
|
/* @__PURE__ */ jsx(ArticleViewTracker, { slug: post.slug, site }),
|
|
@@ -74,8 +74,8 @@ export declare function getArticle(slug: string, options?: {
|
|
|
74
74
|
*
|
|
75
75
|
* `getArticle` returns null for a mistyped or deleted slug, and the page
|
|
76
76
|
* used to carry on rendering a "not found" message with HTTP 200 and an
|
|
77
|
-
* indexable title: a soft 404 on every bad post URL
|
|
78
|
-
*
|
|
77
|
+
* indexable title: a soft 404 on every bad post URL. This calls Next's
|
|
78
|
+
* `notFound()` instead, so the
|
|
79
79
|
* route answers 404 with `noindex`.
|
|
80
80
|
*
|
|
81
81
|
* Call it from `generateMetadata` (or the page) before rendering `Article`:
|
|
@@ -293,7 +293,7 @@ export declare function generateRssFeed(options: RssFeedOptions): Promise<string
|
|
|
293
293
|
export declare function generateAtomFeed(options: RssFeedOptions): Promise<string>;
|
|
294
294
|
/**
|
|
295
295
|
* Fetch all active topic clusters for the project.
|
|
296
|
-
* Uses the real cluster data from
|
|
296
|
+
* Uses the real cluster data from Sonor API (not heuristic-based).
|
|
297
297
|
*/
|
|
298
298
|
export declare function getTopicClusters(options?: {
|
|
299
299
|
site?: string;
|
|
@@ -449,7 +449,7 @@ export declare function generateAuthorPageMetadata(author: ArticleAuthor, option
|
|
|
449
449
|
* keeps its existing public API.
|
|
450
450
|
*/
|
|
451
451
|
export { authorEntityId, generateArticleAuthorNode, generateAuthorPersonSchema, generateAuthorSchema, withArticleAuthorIdentity, type AuthorSchemaOptions, } from './author-schema';
|
|
452
|
-
/**
|
|
452
|
+
/** Sonor article document shape (alias of `Article` from `./types`) */
|
|
453
453
|
export type { Article as ArticleRecord } from './types';
|
|
454
454
|
export { articleCategorySlug, createPublicationRoutes, resolveArticleUrl, resolvePublicationUrl } from './routes';
|
|
455
455
|
export type { ArticleRoutePost, PublicationRoutingOptions } from './routes';
|
package/dist/articles/server.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
export { FEED_DEFAULT_ITEMS, NEWS_SITEMAP_MAX_URLS, NEWS_SITEMAP_WINDOW_MS, SEO_LIMITS, buildNewsSitemapXml, cdata, generateAllArticleSchemas, generateArticleCategoryMetadata, generateArticleListSchema, generateArticleMetadata, generateArticleSchema, generateArticleSitemap, generateArticleStaticParams, generateAtomFeed, generateAuthorPageMetadata, generateAuthorStaticParams, generateBreadcrumbSchema, generateCategoryStaticParams, generateClusterArticleSchema, generateClusterBreadcrumbSchema, generateClusterItemListSchema, generateClusterLandingSchema, generateClusterPageMetadata, generateFaqSchema, generateHowToSchema, generateNewsSitemap, generatePublicationMetadata, generateRssFeed, getAllArticleSlugs, getAllArticles, getAllAuthorSlugs, getArticle, getArticleCategories, getAuthorBySlug, getAuthorPosts, getClusterNavigation, getPostsByCategory, getRelatedInsights, getTopicCluster, getTopicClusters, recentNewsPosts, requireArticle, sanitizeExcerpt, validateArticleSeo, validateMetaDescription, validateSeoTitle } from '../chunk-
|
|
1
|
+
export { FEED_DEFAULT_ITEMS, NEWS_SITEMAP_MAX_URLS, NEWS_SITEMAP_WINDOW_MS, SEO_LIMITS, buildNewsSitemapXml, cdata, generateAllArticleSchemas, generateArticleCategoryMetadata, generateArticleListSchema, generateArticleMetadata, generateArticleSchema, generateArticleSitemap, generateArticleStaticParams, generateAtomFeed, generateAuthorPageMetadata, generateAuthorStaticParams, generateBreadcrumbSchema, generateCategoryStaticParams, generateClusterArticleSchema, generateClusterBreadcrumbSchema, generateClusterItemListSchema, generateClusterLandingSchema, generateClusterPageMetadata, generateFaqSchema, generateHowToSchema, generateNewsSitemap, generatePublicationMetadata, generateRssFeed, getAllArticleSlugs, getAllArticles, getAllAuthorSlugs, getArticle, getArticleCategories, getAuthorBySlug, getAuthorPosts, getClusterNavigation, getPostsByCategory, getRelatedInsights, getTopicCluster, getTopicClusters, recentNewsPosts, requireArticle, sanitizeExcerpt, validateArticleSeo, validateMetaDescription, validateSeoTitle } from '../chunk-PKGN32AU.js';
|
|
2
2
|
export { articleTableCss, wrapArticleTables } from '../chunk-Y3INC4QJ.js';
|
|
3
3
|
export { authorEntityId, generateArticleAuthorNode, generateAuthorPersonSchema, generateAuthorSchema, resolveArticleArtwork, withArticleAuthorIdentity } from '../chunk-QXMIKDOL.js';
|
|
4
4
|
export { articleCategorySlug, createPublicationRoutes, resolveArticleUrl, resolvePublicationUrl } from '../chunk-WMVK77ND.js';
|
|
5
|
+
import '../chunk-VWWITFWM.js';
|
|
5
6
|
import '../chunk-MJP63SSS.js';
|
|
6
7
|
import '../chunk-X6F6SO4S.js';
|
|
7
8
|
import '../chunk-MH2DSGC6.js';
|
package/dist/articles/types.d.ts
CHANGED
|
@@ -125,7 +125,7 @@ export interface ArticleAuthor {
|
|
|
125
125
|
author_page_url?: string;
|
|
126
126
|
/**
|
|
127
127
|
* schema.org `@id` for this person, shared by every site that describes
|
|
128
|
-
* them (blog_authors.entity_id), e.g. `https://
|
|
128
|
+
* them (blog_authors.entity_id), e.g. `https://example.com/#person`.
|
|
129
129
|
* Unset: the kit uses `<author page URL>#person`.
|
|
130
130
|
*/
|
|
131
131
|
entity_id?: string | null;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @sonordev/site-kit/
|
|
2
|
+
* @sonordev/site-kit/chat - Chat Widget (Redesigned)
|
|
3
3
|
*
|
|
4
4
|
* Features:
|
|
5
5
|
* - Pulls brand colors (primary/secondary) + business info from project settings via API
|
|
@@ -17,7 +17,7 @@ interface ChatWidgetProps {
|
|
|
17
17
|
projectId?: string;
|
|
18
18
|
config?: Partial<ChatConfig>;
|
|
19
19
|
apiUrl?: string;
|
|
20
|
-
/** Signal API base URL for direct AI chat (no
|
|
20
|
+
/** Signal API base URL for direct AI chat (no Sonor passthrough) */
|
|
21
21
|
signalUrl?: string;
|
|
22
22
|
/** Clickable question chips shown in the welcome screen before the first message */
|
|
23
23
|
suggested_questions?: string[];
|
|
@@ -63,9 +63,9 @@ interface WidgetConfigFromApi {
|
|
|
63
63
|
* Whether Echo belongs on this site, given the project's widget config.
|
|
64
64
|
*
|
|
65
65
|
* Sonor decides this and sends it as `is_enabled` on `GET /engage/widget/config`:
|
|
66
|
-
* the
|
|
67
|
-
* settings counts as on) and the project's
|
|
68
|
-
*
|
|
66
|
+
* the "Show the chat widget" switch (Messages → Chat settings; a project that
|
|
67
|
+
* never saved chat settings counts as on) and the project's Website chat
|
|
68
|
+
* module (Project Settings), resolved once server-side. Only an explicit `false` hides
|
|
69
69
|
* Echo, which also keeps an API that predates the field showing it. `null`
|
|
70
70
|
* means the config hasn't arrived or couldn't be fetched, and the chat can't
|
|
71
71
|
* run without it either.
|
|
@@ -85,8 +85,9 @@ interface EchoChatProps extends ChatWidgetProps {
|
|
|
85
85
|
/**
|
|
86
86
|
* Echo itself, mounted by ChatWidget once the project's config says chat is
|
|
87
87
|
* on. Exported for the launcher tests, which render it with a resolved config
|
|
88
|
-
* because the package's vitest has no DOM to run ChatWidget's fetch in.
|
|
89
|
-
*
|
|
88
|
+
* because the package's vitest has no DOM to run ChatWidget's fetch in.
|
|
89
|
+
* `@sonordev/site-kit/chat` re-exports it, but a site should mount ChatWidget
|
|
90
|
+
* (or SiteChat), which fetches the config and follows the project's switch.
|
|
90
91
|
*/
|
|
91
92
|
export declare function EchoChat({ projectId, widgetConfig, config, apiUrl: propApiUrl, signalUrl: propSignalUrl, suggested_questions: propSuggestedQuestions, assistant_name: propAssistantName, welcome_message: propWelcomeMessage, assistant_avatar: propAssistantAvatar }: EchoChatProps): React.JSX.Element;
|
|
92
93
|
export {};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @sonordev/site-kit/
|
|
2
|
+
* @sonordev/site-kit/chat - Echo UI Actions
|
|
3
3
|
*
|
|
4
4
|
* Renders the optional `uiActions` the visitor Echo concierge returns alongside
|
|
5
|
-
* a chat reply
|
|
5
|
+
* a chat reply. Rendered beneath the assistant
|
|
6
6
|
* message in ChatWidget, on-brand with the widget's primary-color tokens and
|
|
7
7
|
* the brand foreground colours from brand-color.ts.
|
|
8
8
|
*
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
* forms `useForm` fetch/validate/submit path) with optional prefill.
|
|
11
11
|
* - suggest_action → clickable chip; sends the message as the next turn, or
|
|
12
12
|
* navigates when the action is a path/URL.
|
|
13
|
-
* - show_portfolio_item → intentionally ignored
|
|
14
|
-
*
|
|
13
|
+
* - show_portfolio_item → intentionally ignored: the generic widget has no
|
|
14
|
+
* portfolio view; a site with its own chat UI handles it.
|
|
15
15
|
*/
|
|
16
16
|
import React from 'react';
|
|
17
17
|
import type { UiAction } from './types';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sonordev/site-kit/chat - SiteChat: the Website chat a site shows
|
|
3
|
+
* (Sonor → Messages).
|
|
4
|
+
*
|
|
5
|
+
* Echo's launcher, mounted once the browser is idle. SiteKitLayout mounts it
|
|
6
|
+
* for you (its `chat` prop); mount it yourself only on a site without
|
|
7
|
+
* SiteKitLayout. ChatWidget, its markdown renderer and its socket download
|
|
8
|
+
* when it first renders, never with the page. It shows only while the
|
|
9
|
+
* project's chat is switched on in Sonor (see ChatWidget's isChatEnabled).
|
|
10
|
+
*/
|
|
11
|
+
import React from 'react';
|
|
12
|
+
import type { ChatLauncherPlacement } from './types';
|
|
13
|
+
import { type AnalyticsGateOptions } from '../shared/reporting-gate';
|
|
14
|
+
export interface SiteChatProps extends ChatLauncherPlacement, AnalyticsGateOptions {
|
|
15
|
+
apiUrl?: string;
|
|
16
|
+
apiKey?: string;
|
|
17
|
+
/** For chat routing. Resolved from the API key when absent. */
|
|
18
|
+
projectId?: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Same gate as analytics (frames, localhost, a key to send with): a chat
|
|
22
|
+
* launcher in a case study's device frame would talk to the agency's visitor,
|
|
23
|
+
* not this site's.
|
|
24
|
+
*/
|
|
25
|
+
export declare function SiteChat(props: SiteChatProps): React.JSX.Element | null;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @sonordev/site-kit/
|
|
2
|
+
* @sonordev/site-kit/chat — Echo's brand colours
|
|
3
3
|
*
|
|
4
4
|
* Single source of truth for how Echo turns the site's brand colour into
|
|
5
5
|
* foreground colours. ChatWidget and EchoUiActions route every such decision
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* when it already reads, otherwise the brand pulled toward black (light
|
|
15
15
|
* panel) or white (dark panel) just far enough to clear WCAG AA.
|
|
16
16
|
*
|
|
17
|
-
* Why: a light brand (
|
|
17
|
+
* Why: a light brand (a #d4af37 gold, any yellow) drawn as text
|
|
18
18
|
* on the ~86% white panel sat at about 2:1.
|
|
19
19
|
*/
|
|
20
20
|
/** Light enough that text and icons on a fill of it should be dark. Unreadable colours count as dark. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @sonordev/site-kit/
|
|
2
|
+
* @sonordev/site-kit/chat — Echo's transcript: message shapes and turns
|
|
3
3
|
*
|
|
4
4
|
* Single source of truth for what ChatWidget adds to the transcript when a
|
|
5
5
|
* visitor speaks, and for the one AI turn every send path goes through.
|
package/dist/chat/index.d.ts
CHANGED
|
@@ -2,10 +2,14 @@
|
|
|
2
2
|
* @sonordev/site-kit/chat — Website chat (Sonor → Messages).
|
|
3
3
|
*
|
|
4
4
|
* The chat launcher and Echo conversation a site shows. SiteKitLayout mounts
|
|
5
|
-
* it for you (its `chat` prop
|
|
6
|
-
*
|
|
5
|
+
* it for you (its `chat` prop); `SiteChat` places it yourself the same way
|
|
6
|
+
* (idle-deferred, gated like analytics), and `ChatWidget` is the widget
|
|
7
|
+
* itself. `@sonordev/site-kit/engage` (deprecated) re-exports these.
|
|
7
8
|
*/
|
|
8
|
-
export {
|
|
9
|
-
export {
|
|
10
|
-
export
|
|
11
|
-
export type {
|
|
9
|
+
export { SiteChat, type SiteChatProps } from './SiteChat';
|
|
10
|
+
export { ChatWidget, EchoChat, isChatEnabled } from './ChatWidget';
|
|
11
|
+
export { chatLauncherStyles, DEFAULT_LAUNCHER_OFFSET_BOTTOM } from './launcher-placement';
|
|
12
|
+
export type { ChatLauncherStyles } from './launcher-placement';
|
|
13
|
+
export { SONOR_PUBLIC_ECHO_DEFAULTS, getEchoWidgetProps } from './echo-config';
|
|
14
|
+
export type { EchoPublicConfig } from './echo-config';
|
|
15
|
+
export type { ChatAvailability, ChatConfig, ChatConversation, ChatLauncherPlacement, ChatLauncherPosition, ChatMessage, UiAction, UiActionType, } from './types';
|
package/dist/chat/index.js
CHANGED
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
export {
|
|
3
|
-
|
|
4
|
-
export {
|
|
2
|
+
export { SONOR_PUBLIC_ECHO_DEFAULTS, getEchoWidgetProps } from '../chunk-HODO5BX5.js';
|
|
3
|
+
export { ChatWidget, DEFAULT_LAUNCHER_OFFSET_BOTTOM, EchoChat, chatLauncherStyles, isChatEnabled } from '../chunk-64DKGVEI.js';
|
|
4
|
+
export { SiteChat } from '../chunk-NV72HZ4W.js';
|
|
5
5
|
import '../chunk-6T6CQVNL.js';
|
|
6
|
-
import '../chunk-
|
|
7
|
-
import '../chunk-
|
|
6
|
+
import '../chunk-JE4A5S4F.js';
|
|
7
|
+
import '../chunk-27FISYK4.js';
|
|
8
|
+
import '../chunk-FR6BYFPC.js';
|
|
9
|
+
import '../chunk-Q6E4OPGG.js';
|
|
10
|
+
import '../chunk-C2FZBUSS.js';
|
|
8
11
|
import '../chunk-5SQK3D53.js';
|
|
12
|
+
import '../chunk-HW7B43E5.js';
|
|
9
13
|
import '../chunk-NJCTQH2P.js';
|
|
10
14
|
import '../chunk-S22FSH7C.js';
|
|
11
15
|
import '../chunk-L2V5PUFN.js';
|
|
12
16
|
import '../chunk-GJWI74ZZ.js';
|
|
13
|
-
import '../chunk-
|
|
14
|
-
import '../chunk-
|
|
15
|
-
import '../chunk-
|
|
17
|
+
import '../chunk-43OCZ3JA.js';
|
|
18
|
+
import '../chunk-EKBEOXTH.js';
|
|
19
|
+
import '../chunk-D6ZC7XKZ.js';
|
|
20
|
+
import '../chunk-K4ZHAURD.js';
|
|
21
|
+
import '../chunk-F24FNCTK.js';
|
|
16
22
|
import '../chunk-PKBMQBKP.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @sonordev/site-kit/
|
|
2
|
+
* @sonordev/site-kit/chat - Chat launcher placement
|
|
3
3
|
*
|
|
4
4
|
* Single source of truth for where the Echo launcher sits and, derived from
|
|
5
5
|
* it, where the chat popup opens, on screen and in the stacking order.
|
|
@@ -14,12 +14,6 @@ import type { CSSProperties } from 'react';
|
|
|
14
14
|
import type { ChatLauncherPlacement } from './types';
|
|
15
15
|
/** Launcher clearance above the bottom edge when a site sets nothing. */
|
|
16
16
|
export declare const DEFAULT_LAUNCHER_OFFSET_BOTTOM = "20px";
|
|
17
|
-
/**
|
|
18
|
-
* Layer everything Engage renders stacks on when a site sets nothing:
|
|
19
|
-
* popups, nudges, bars and the chat launcher, with the chat popup one below.
|
|
20
|
-
* EngageWidget's default comes from here too.
|
|
21
|
-
*/
|
|
22
|
-
export declare const DEFAULT_ENGAGE_Z_INDEX = 9999;
|
|
23
17
|
/**
|
|
24
18
|
* Custom property a stylesheet can set to move the launcher. Wins over the
|
|
25
19
|
* `offsetBottom` option. Deliberately never declared by the kit: a property
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { Socket } from 'socket.io-client';
|
|
2
2
|
/**
|
|
3
3
|
* Lazy socket.io loader — kept in a separate file so bundlers
|
|
4
|
-
* (Turbopack, webpack) never pull socket.io-client into the
|
|
5
|
-
*
|
|
4
|
+
* (Turbopack, webpack) never pull socket.io-client into the chat
|
|
5
|
+
* chunk. Only loaded when the user actually opens the chat.
|
|
6
6
|
*
|
|
7
7
|
* This module owns site-kit's entire socket.io surface. If you are wondering
|
|
8
8
|
* why package.json declares `engine.io-client` and `socket.io-parser` when
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sonordev/site-kit/chat: Website chat types (Sonor → Messages).
|
|
3
|
+
*/
|
|
4
|
+
/** The corner the Echo chat launcher sits in. */
|
|
5
|
+
export type ChatLauncherPosition = 'bottom-right' | 'bottom-left';
|
|
6
|
+
/**
|
|
7
|
+
* Where the Echo chat launcher sits, including the layer it stacks on. The
|
|
8
|
+
* single definition of launcher placement: the layout's `chat` config,
|
|
9
|
+
* SiteChat's props and ChatConfig all extend it, so a new placement option is
|
|
10
|
+
* added once. ChatWidget turns it into styles through `chatLauncherStyles`
|
|
11
|
+
* (./launcher-placement).
|
|
12
|
+
*/
|
|
13
|
+
export interface ChatLauncherPlacement {
|
|
14
|
+
/** Corner. Default: 'bottom-right' */
|
|
15
|
+
position?: ChatLauncherPosition;
|
|
16
|
+
/**
|
|
17
|
+
* Distance from the bottom of the viewport to the launcher, as any CSS
|
|
18
|
+
* length (`'88px'`, `'5.5rem'`, `'calc(4rem + 8px)'`). A number is pixels.
|
|
19
|
+
* Default: `'20px'`.
|
|
20
|
+
*
|
|
21
|
+
* The device's safe-area inset is added on top, so pass the clearance you
|
|
22
|
+
* want above your own UI, not the inset. The chat popup opens above the
|
|
23
|
+
* launcher wherever this puts it.
|
|
24
|
+
*
|
|
25
|
+
* A `--sk-echo-offset-bottom` custom property set anywhere above the
|
|
26
|
+
* launcher (`:root`, `body`, a media query, a `:has()` rule) wins over this
|
|
27
|
+
* value. Use that when the offset depends on the page or the breakpoint,
|
|
28
|
+
* such as clearing a sticky bar that only some pages render.
|
|
29
|
+
*/
|
|
30
|
+
offsetBottom?: string | number;
|
|
31
|
+
/**
|
|
32
|
+
* Stacking layer. The launcher sits on it and the chat popup one layer
|
|
33
|
+
* beneath. Default: 9999.
|
|
34
|
+
*
|
|
35
|
+
* Through SiteKitLayout the same number also stacks popups, banners and
|
|
36
|
+
* toasts, so everything a site's widgets render shares one layer. Lower it
|
|
37
|
+
* when the site's own fixed UI (a mobile menu, a cookie banner) has to
|
|
38
|
+
* cover the chat.
|
|
39
|
+
*/
|
|
40
|
+
zIndex?: number;
|
|
41
|
+
}
|
|
42
|
+
export interface ChatConfig extends ChatLauncherPlacement {
|
|
43
|
+
/** Widget position */
|
|
44
|
+
position: ChatLauncherPosition;
|
|
45
|
+
/** Widget appearance */
|
|
46
|
+
buttonIcon?: 'chat' | 'help' | 'custom';
|
|
47
|
+
buttonColor?: string;
|
|
48
|
+
buttonText?: string;
|
|
49
|
+
/** Brand primary color */
|
|
50
|
+
brandPrimary?: string;
|
|
51
|
+
/** Welcome message */
|
|
52
|
+
welcomeMessage?: string;
|
|
53
|
+
/** Operating hours */
|
|
54
|
+
operatingHours?: {
|
|
55
|
+
enabled: boolean;
|
|
56
|
+
timezone: string;
|
|
57
|
+
hours: {
|
|
58
|
+
[day: number]: {
|
|
59
|
+
start: string;
|
|
60
|
+
end: string;
|
|
61
|
+
} | null;
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
/** AI vs Live Chat */
|
|
65
|
+
mode: 'ai' | 'live' | 'hybrid';
|
|
66
|
+
/** AI settings (if mode is 'ai' or 'hybrid') */
|
|
67
|
+
aiSettings?: {
|
|
68
|
+
skillId?: string;
|
|
69
|
+
handoffToLive?: boolean;
|
|
70
|
+
handoffKeywords?: string[];
|
|
71
|
+
/** When AI should suggest handoff based on sentiment or keywords */
|
|
72
|
+
handoffTriggers?: {
|
|
73
|
+
negativesentiment?: boolean;
|
|
74
|
+
keywords?: string[];
|
|
75
|
+
afterMessages?: number;
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
/** Offline mode settings (when no agents available) */
|
|
79
|
+
offlineMode?: 'form' | 'ai' | 'message';
|
|
80
|
+
/** Form slug to show when offline (defaults to 'contact') */
|
|
81
|
+
offlineFormSlug?: string;
|
|
82
|
+
/** AI fallback when no agents online (hybrid mode) */
|
|
83
|
+
aiFallbackEnabled?: boolean;
|
|
84
|
+
/** Custom offline message */
|
|
85
|
+
offlineMessage?: string;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* UI actions the visitor Echo endpoint (POST /echo/public/chat) may return on
|
|
89
|
+
* the JSON response alongside `content` / `conversationId`. The chat widget
|
|
90
|
+
* renders each as an inline card or chip beneath the assistant message.
|
|
91
|
+
*
|
|
92
|
+
* This mirrors the shape Echo's endpoint sends. It is a LOCAL contract on
|
|
93
|
+
* purpose: the kit never imports from the API.
|
|
94
|
+
*
|
|
95
|
+
* - `show_form` → data.formSlug (+ optional data.prefill) — offer the managed form inline.
|
|
96
|
+
* - `suggest_action` → data.action + data.message — clickable chip (send message or navigate).
|
|
97
|
+
* - `show_portfolio_item` → data.slug — the generic widget ignores it (a site's own chat UI handles it).
|
|
98
|
+
*/
|
|
99
|
+
export type UiActionType = 'show_form' | 'suggest_action' | 'show_portfolio_item';
|
|
100
|
+
export interface UiAction {
|
|
101
|
+
type: UiActionType | string;
|
|
102
|
+
data: Record<string, unknown>;
|
|
103
|
+
}
|
|
104
|
+
export interface ChatMessage {
|
|
105
|
+
id: string;
|
|
106
|
+
conversation_id: string;
|
|
107
|
+
role: 'user' | 'assistant' | 'agent' | 'system';
|
|
108
|
+
content: string;
|
|
109
|
+
metadata?: Record<string, unknown>;
|
|
110
|
+
created_at: string;
|
|
111
|
+
/** Name of the agent (for agent messages) */
|
|
112
|
+
sender_name?: string;
|
|
113
|
+
/** Avatar URL of the agent */
|
|
114
|
+
sender_avatar?: string;
|
|
115
|
+
}
|
|
116
|
+
export interface ChatConversation {
|
|
117
|
+
id: string;
|
|
118
|
+
project_id: string;
|
|
119
|
+
visitor_id: string;
|
|
120
|
+
status: 'active' | 'ai' | 'pending_handoff' | 'human' | 'closed';
|
|
121
|
+
assigned_to?: string;
|
|
122
|
+
last_message_at: string;
|
|
123
|
+
created_at: string;
|
|
124
|
+
/** AI summary of the conversation */
|
|
125
|
+
ai_summary?: string;
|
|
126
|
+
/** Visitor info */
|
|
127
|
+
visitor_name?: string;
|
|
128
|
+
visitor_email?: string;
|
|
129
|
+
}
|
|
130
|
+
/** Availability status returned by the widget API */
|
|
131
|
+
export interface ChatAvailability {
|
|
132
|
+
available: boolean;
|
|
133
|
+
mode: 'live' | 'ai' | 'offline';
|
|
134
|
+
agentsOnline: number;
|
|
135
|
+
operatingHoursActive: boolean;
|
|
136
|
+
}
|