@burdenoff/website-sdk 2026.922.3 → 2026.922.5

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.
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
2
- import { E as ExploreProduct } from '../explore-types-CPF1QoMn.mjs';
2
+ import { E as ExploreProduct, a as ExploreReference } from '../explore-types-DvQPiL1t.mjs';
3
3
 
4
4
  interface ExplorePageProps {
5
5
  /**
@@ -85,6 +85,96 @@ declare function inlineImageOrigins(products: readonly Pick<ExploreProduct, "web
85
85
  * that slips an arbitrary URL past it still cannot make the visitor's browser fetch it.
86
86
  */
87
87
  declare function isInlineImageAllowed(src: unknown, origins: ReadonlySet<string>): src is string;
88
+ /**
89
+ * The kinds of page an answer can cite.
90
+ *
91
+ * `PAGE` is the catch-all for a catalog site's own marketing pages, so the list is total for
92
+ * anything on one of our origins; a reference that is NOT on a catalog origin gets no kind at
93
+ * all (see `referenceKindOf`).
94
+ */
95
+ type ExploreReferenceKind = "CONCEPT" | "DOCS" | "PRICING" | "USE_CASE" | "PAGE";
96
+ /**
97
+ * What KIND of page a reference points at, decided from its URL alone.
98
+ *
99
+ * Deliberately not from the title: titles are model-written prose in six languages, so
100
+ * "Pricing" in one answer is "Precios" in the next and "Plans and pricing" in the one after.
101
+ * The URL is the only part of a reference nobody paraphrases.
102
+ *
103
+ * Reasoned against the catalog origins exactly as `isInlineImageAllowed` is: a URL that is
104
+ * not on a product site we list gets `null` rather than a guessed label, because the whole
105
+ * value of the row is that it says what the evidence IS.
106
+ */
107
+ declare function referenceKindOf(url: string, origins: ReadonlySet<string>): ExploreReferenceKind | null;
108
+ /**
109
+ * Apex origin → the product's display name, built from the catalog the same way
110
+ * `inlineImageOrigins` builds its allow-list.
111
+ *
112
+ * The display name matters: `ExploreReference.product` carries the slug, so a row built from
113
+ * it says "vibecontrols" next to a page that calls itself VibeControls everywhere else.
114
+ */
115
+ declare function productNamesByOrigin(products: readonly Pick<ExploreProduct, "name" | "website">[]): Map<string, string>;
116
+ /** The shape of one answer's evidence, as the chips render it. */
117
+ interface ExploreProvenance {
118
+ /** Every reference the answer cites, including any we could not classify. */
119
+ total: number;
120
+ /** Kinds present, in `REFERENCE_KIND_ORDER`, with how many sources each covers. */
121
+ kinds: Array<{
122
+ kind: ExploreReferenceKind;
123
+ count: number;
124
+ }>;
125
+ /** Product names, in the order the answer first cited them. */
126
+ products: string[];
127
+ }
128
+ /**
129
+ * Summarise what an answer is grounded in. Pure, and derived entirely from `references` —
130
+ * there is no backend field behind this row.
131
+ */
132
+ declare function summariseReferences(references: readonly ExploreReference[], origins: ReadonlySet<string>, productNames: ReadonlyMap<string, string>): ExploreProvenance;
133
+ /**
134
+ * An answer as READABLE TEXT, for the clipboard.
135
+ *
136
+ * What counts as "our internal markup artefacts", and why each choice:
137
+ *
138
+ * - **Image embeds go.** `![Concept illustration of …](https://…/01.webp)` is a picture this
139
+ * page injected into the answer; pasted into an email it is a URL and an alt string, and
140
+ * neither is the answer. The caption line the backend writes under it is ordinary prose and
141
+ * stays.
142
+ * - **Links become `label (url)`.** The destination is information the reader may need; the
143
+ * bracket-paren syntax is not. Dropping the URL would quietly strip the page it came from.
144
+ * - **Citation markers `[3]` stay.** They are the only attribution the copied text carries,
145
+ * and they are the answer's own — not something the UI added. The sources they point at are
146
+ * listed right next to the button that copied this.
147
+ * - **Emphasis, headings, blockquote and rule markers go**, because `**` and `###` are
148
+ * instructions to a renderer, not words.
149
+ * - **A table keeps its pipes.** Pasted into a README, an issue or a chat it is a table
150
+ * again; flattened into sentences it is not.
151
+ * - **Fenced code is verbatim**, fences included, minus nothing but the fence lines
152
+ * themselves: stripping `*` or `_` inside a code block would corrupt the code.
153
+ *
154
+ * Built from `message.content` rather than from the rendered DOM: `textContent` on the bubble
155
+ * would fold every paragraph, list item and table cell into one run-on line.
156
+ */
157
+ declare function answerPlainText(markdown: string): string;
158
+ /**
159
+ * The same answer as something to SAY, for read-aloud.
160
+ *
161
+ * It shares every rule above but the two that are right for a paste and wrong for a voice:
162
+ *
163
+ * - **A link is its label.** The clipboard keeps `label (https://…)` because a pasted answer
164
+ * loses the page otherwise. Spoken, that is a URL spelled out character by character in
165
+ * the middle of a sentence — and the prompt asks for two to five links in every answer, so
166
+ * it is not an edge case. The sources are listed under the answer either way.
167
+ * - **A table is read as rows, not as pipes.** `| --- | --- |` is a line of punctuation and
168
+ * the pipes are column rules, neither of which is a word. Each row is read with its cells
169
+ * under their own column headings — the phone layout, out loud — so a plan list still says
170
+ * which number is the price. Comparisons and plan lists are exactly the answers the
171
+ * feature was built for (CONTRACT.md §7), which is what makes this worth a second mode.
172
+ *
173
+ * Everything else stays deliberately identical, including citation markers: they are the
174
+ * answer's own attribution in both, and a listener hearing "two" after a claim is hearing
175
+ * the same thing a reader sees.
176
+ */
177
+ declare function answerSpeechText(markdown: string): string;
88
178
  declare function ExplorePage({ seo, productSlug, examplePrompts, className, heightMode, viewportOffset, onNavigate, onSend, welcomeTitle, welcomeBody, locale, }: ExplorePageProps): react.JSX.Element;
89
179
 
90
- export { ExplorePage, type ExplorePageProps, inlineImageOrigins, isInlineImageAllowed, logoUrlOf };
180
+ export { ExplorePage, type ExplorePageProps, type ExploreProvenance, type ExploreReferenceKind, answerPlainText, answerSpeechText, inlineImageOrigins, isInlineImageAllowed, logoUrlOf, productNamesByOrigin, referenceKindOf, summariseReferences };
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
2
- import { E as ExploreProduct } from '../explore-types-CPF1QoMn.js';
2
+ import { E as ExploreProduct, a as ExploreReference } from '../explore-types-DvQPiL1t.js';
3
3
 
4
4
  interface ExplorePageProps {
5
5
  /**
@@ -85,6 +85,96 @@ declare function inlineImageOrigins(products: readonly Pick<ExploreProduct, "web
85
85
  * that slips an arbitrary URL past it still cannot make the visitor's browser fetch it.
86
86
  */
87
87
  declare function isInlineImageAllowed(src: unknown, origins: ReadonlySet<string>): src is string;
88
+ /**
89
+ * The kinds of page an answer can cite.
90
+ *
91
+ * `PAGE` is the catch-all for a catalog site's own marketing pages, so the list is total for
92
+ * anything on one of our origins; a reference that is NOT on a catalog origin gets no kind at
93
+ * all (see `referenceKindOf`).
94
+ */
95
+ type ExploreReferenceKind = "CONCEPT" | "DOCS" | "PRICING" | "USE_CASE" | "PAGE";
96
+ /**
97
+ * What KIND of page a reference points at, decided from its URL alone.
98
+ *
99
+ * Deliberately not from the title: titles are model-written prose in six languages, so
100
+ * "Pricing" in one answer is "Precios" in the next and "Plans and pricing" in the one after.
101
+ * The URL is the only part of a reference nobody paraphrases.
102
+ *
103
+ * Reasoned against the catalog origins exactly as `isInlineImageAllowed` is: a URL that is
104
+ * not on a product site we list gets `null` rather than a guessed label, because the whole
105
+ * value of the row is that it says what the evidence IS.
106
+ */
107
+ declare function referenceKindOf(url: string, origins: ReadonlySet<string>): ExploreReferenceKind | null;
108
+ /**
109
+ * Apex origin → the product's display name, built from the catalog the same way
110
+ * `inlineImageOrigins` builds its allow-list.
111
+ *
112
+ * The display name matters: `ExploreReference.product` carries the slug, so a row built from
113
+ * it says "vibecontrols" next to a page that calls itself VibeControls everywhere else.
114
+ */
115
+ declare function productNamesByOrigin(products: readonly Pick<ExploreProduct, "name" | "website">[]): Map<string, string>;
116
+ /** The shape of one answer's evidence, as the chips render it. */
117
+ interface ExploreProvenance {
118
+ /** Every reference the answer cites, including any we could not classify. */
119
+ total: number;
120
+ /** Kinds present, in `REFERENCE_KIND_ORDER`, with how many sources each covers. */
121
+ kinds: Array<{
122
+ kind: ExploreReferenceKind;
123
+ count: number;
124
+ }>;
125
+ /** Product names, in the order the answer first cited them. */
126
+ products: string[];
127
+ }
128
+ /**
129
+ * Summarise what an answer is grounded in. Pure, and derived entirely from `references` —
130
+ * there is no backend field behind this row.
131
+ */
132
+ declare function summariseReferences(references: readonly ExploreReference[], origins: ReadonlySet<string>, productNames: ReadonlyMap<string, string>): ExploreProvenance;
133
+ /**
134
+ * An answer as READABLE TEXT, for the clipboard.
135
+ *
136
+ * What counts as "our internal markup artefacts", and why each choice:
137
+ *
138
+ * - **Image embeds go.** `![Concept illustration of …](https://…/01.webp)` is a picture this
139
+ * page injected into the answer; pasted into an email it is a URL and an alt string, and
140
+ * neither is the answer. The caption line the backend writes under it is ordinary prose and
141
+ * stays.
142
+ * - **Links become `label (url)`.** The destination is information the reader may need; the
143
+ * bracket-paren syntax is not. Dropping the URL would quietly strip the page it came from.
144
+ * - **Citation markers `[3]` stay.** They are the only attribution the copied text carries,
145
+ * and they are the answer's own — not something the UI added. The sources they point at are
146
+ * listed right next to the button that copied this.
147
+ * - **Emphasis, headings, blockquote and rule markers go**, because `**` and `###` are
148
+ * instructions to a renderer, not words.
149
+ * - **A table keeps its pipes.** Pasted into a README, an issue or a chat it is a table
150
+ * again; flattened into sentences it is not.
151
+ * - **Fenced code is verbatim**, fences included, minus nothing but the fence lines
152
+ * themselves: stripping `*` or `_` inside a code block would corrupt the code.
153
+ *
154
+ * Built from `message.content` rather than from the rendered DOM: `textContent` on the bubble
155
+ * would fold every paragraph, list item and table cell into one run-on line.
156
+ */
157
+ declare function answerPlainText(markdown: string): string;
158
+ /**
159
+ * The same answer as something to SAY, for read-aloud.
160
+ *
161
+ * It shares every rule above but the two that are right for a paste and wrong for a voice:
162
+ *
163
+ * - **A link is its label.** The clipboard keeps `label (https://…)` because a pasted answer
164
+ * loses the page otherwise. Spoken, that is a URL spelled out character by character in
165
+ * the middle of a sentence — and the prompt asks for two to five links in every answer, so
166
+ * it is not an edge case. The sources are listed under the answer either way.
167
+ * - **A table is read as rows, not as pipes.** `| --- | --- |` is a line of punctuation and
168
+ * the pipes are column rules, neither of which is a word. Each row is read with its cells
169
+ * under their own column headings — the phone layout, out loud — so a plan list still says
170
+ * which number is the price. Comparisons and plan lists are exactly the answers the
171
+ * feature was built for (CONTRACT.md §7), which is what makes this worth a second mode.
172
+ *
173
+ * Everything else stays deliberately identical, including citation markers: they are the
174
+ * answer's own attribution in both, and a listener hearing "two" after a claim is hearing
175
+ * the same thing a reader sees.
176
+ */
177
+ declare function answerSpeechText(markdown: string): string;
88
178
  declare function ExplorePage({ seo, productSlug, examplePrompts, className, heightMode, viewportOffset, onNavigate, onSend, welcomeTitle, welcomeBody, locale, }: ExplorePageProps): react.JSX.Element;
89
179
 
90
- export { ExplorePage, type ExplorePageProps, inlineImageOrigins, isInlineImageAllowed, logoUrlOf };
180
+ export { ExplorePage, type ExplorePageProps, type ExploreProvenance, type ExploreReferenceKind, answerPlainText, answerSpeechText, inlineImageOrigins, isInlineImageAllowed, logoUrlOf, productNamesByOrigin, referenceKindOf, summariseReferences };