@tomehq/theme 0.6.3 → 0.7.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/dist/ai-api-6KVITVN6.js +14 -0
- package/dist/{chunk-26CZLWVW.js → chunk-6AD5TJ6F.js} +426 -87
- package/dist/chunk-LNWYFDZ4.js +73 -0
- package/dist/entry.js +2 -1
- package/dist/index.d.ts +250 -4
- package/dist/index.js +2 -1
- package/package.json +3 -3
- package/src/AiChat.tsx +11 -74
- package/src/Shell.tsx +168 -17
- package/src/__tests__/ai-api.test.ts +42 -0
- package/src/__tests__/ai-search.test.tsx +205 -0
- package/src/__tests__/feedback-widget.test.tsx +132 -0
- package/src/ai-api.ts +110 -0
- package/src/entry-helpers.ts +8 -3
- package/src/entry.test.tsx +6 -22
- package/src/entry.tsx +3 -1
- package/src/presets.ts +93 -3
- package/src/routing.test.ts +2 -3
- package/src/routing.ts +12 -4
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildSystemPrompt,
|
|
3
|
+
callAnthropic,
|
|
4
|
+
callOpenAI,
|
|
5
|
+
getDefaultModel
|
|
6
|
+
} from "./chunk-LNWYFDZ4.js";
|
|
7
|
+
|
|
1
8
|
// src/entry.tsx
|
|
2
9
|
import { useState as useState3, useEffect as useEffect3, useCallback as useCallback3, useRef as useRef3 } from "react";
|
|
3
10
|
import { createRoot } from "react-dom/client";
|
|
@@ -85,7 +92,7 @@ var THEME_PRESETS = {
|
|
|
85
92
|
bd: "#1a1a25",
|
|
86
93
|
tx: "#d4ff00",
|
|
87
94
|
tx2: "#8a90a0",
|
|
88
|
-
txM: "#
|
|
95
|
+
txM: "#7e8494",
|
|
89
96
|
ac: "#6666ff",
|
|
90
97
|
acD: "rgba(102,102,255,0.10)",
|
|
91
98
|
acT: "#8080ff",
|
|
@@ -101,7 +108,7 @@ var THEME_PRESETS = {
|
|
|
101
108
|
bd: "#d0d4db",
|
|
102
109
|
tx: "#0f1219",
|
|
103
110
|
tx2: "#4a5060",
|
|
104
|
-
txM: "#
|
|
111
|
+
txM: "#5c6272",
|
|
105
112
|
ac: "#2020cc",
|
|
106
113
|
acD: "rgba(32,32,204,0.08)",
|
|
107
114
|
acT: "#1a1aa8",
|
|
@@ -120,7 +127,7 @@ var THEME_PRESETS = {
|
|
|
120
127
|
bd: "#21262d",
|
|
121
128
|
tx: "#e6edf3",
|
|
122
129
|
tx2: "#8b949e",
|
|
123
|
-
txM: "#
|
|
130
|
+
txM: "#7d858f",
|
|
124
131
|
ac: "#0ea371",
|
|
125
132
|
acD: "rgba(14,163,113,0.10)",
|
|
126
133
|
acT: "#2dd4a0",
|
|
@@ -146,6 +153,216 @@ var THEME_PRESETS = {
|
|
|
146
153
|
hdBg: "rgba(255,255,255,0.90)"
|
|
147
154
|
},
|
|
148
155
|
fonts: { heading: "Inter", body: "Inter", code: "Fira Code" }
|
|
156
|
+
},
|
|
157
|
+
ocean: {
|
|
158
|
+
dark: {
|
|
159
|
+
bg: "#0a1628",
|
|
160
|
+
sf: "#0f1d33",
|
|
161
|
+
sfH: "#142540",
|
|
162
|
+
bd: "#1a2e50",
|
|
163
|
+
tx: "#e0e8f0",
|
|
164
|
+
tx2: "#8ca0b8",
|
|
165
|
+
txM: "#7b92aa",
|
|
166
|
+
ac: "#0ea5e9",
|
|
167
|
+
acD: "rgba(14,165,233,0.10)",
|
|
168
|
+
acT: "#38bdf8",
|
|
169
|
+
cdBg: "#081320",
|
|
170
|
+
cdTx: "#94b4d0",
|
|
171
|
+
sbBg: "#0a1628",
|
|
172
|
+
hdBg: "rgba(10,22,40,0.90)"
|
|
173
|
+
},
|
|
174
|
+
light: {
|
|
175
|
+
bg: "#f0f7ff",
|
|
176
|
+
sf: "#ffffff",
|
|
177
|
+
sfH: "#e8f0fa",
|
|
178
|
+
bd: "#ccdcef",
|
|
179
|
+
tx: "#0c1929",
|
|
180
|
+
tx2: "#3d5a78",
|
|
181
|
+
txM: "#4a6a88",
|
|
182
|
+
ac: "#0369a1",
|
|
183
|
+
acD: "rgba(3,105,161,0.07)",
|
|
184
|
+
acT: "#025e8f",
|
|
185
|
+
cdBg: "#e4edf7",
|
|
186
|
+
cdTx: "#1a3050",
|
|
187
|
+
sbBg: "#eef4fc",
|
|
188
|
+
hdBg: "rgba(240,247,255,0.92)"
|
|
189
|
+
},
|
|
190
|
+
fonts: { heading: "Outfit", body: "Inter", code: "JetBrains Mono" }
|
|
191
|
+
},
|
|
192
|
+
rose: {
|
|
193
|
+
dark: {
|
|
194
|
+
bg: "#0f0a10",
|
|
195
|
+
sf: "#171118",
|
|
196
|
+
sfH: "#1e1620",
|
|
197
|
+
bd: "#2a1f2c",
|
|
198
|
+
tx: "#f0e4f0",
|
|
199
|
+
tx2: "#b09ab0",
|
|
200
|
+
txM: "#8a7890",
|
|
201
|
+
ac: "#f43f5e",
|
|
202
|
+
acD: "rgba(244,63,94,0.10)",
|
|
203
|
+
acT: "#fb7185",
|
|
204
|
+
cdBg: "#0d080e",
|
|
205
|
+
cdTx: "#c8aec8",
|
|
206
|
+
sbBg: "#0f0a10",
|
|
207
|
+
hdBg: "rgba(15,10,16,0.88)"
|
|
208
|
+
},
|
|
209
|
+
light: {
|
|
210
|
+
bg: "#fef7f7",
|
|
211
|
+
sf: "#ffffff",
|
|
212
|
+
sfH: "#fceef0",
|
|
213
|
+
bd: "#f0d4d8",
|
|
214
|
+
tx: "#1a0f12",
|
|
215
|
+
tx2: "#6b4048",
|
|
216
|
+
txM: "#8a5a64",
|
|
217
|
+
ac: "#c81e3e",
|
|
218
|
+
acD: "rgba(200,30,62,0.06)",
|
|
219
|
+
acT: "#a81835",
|
|
220
|
+
cdBg: "#f8eaec",
|
|
221
|
+
cdTx: "#3a1a22",
|
|
222
|
+
sbBg: "#fdf2f4",
|
|
223
|
+
hdBg: "rgba(254,247,247,0.92)"
|
|
224
|
+
},
|
|
225
|
+
fonts: { heading: "Playfair Display", body: "Source Sans 3", code: "Fira Code" }
|
|
226
|
+
},
|
|
227
|
+
forest: {
|
|
228
|
+
dark: {
|
|
229
|
+
bg: "#091209",
|
|
230
|
+
sf: "#0f1a0f",
|
|
231
|
+
sfH: "#152215",
|
|
232
|
+
bd: "#1e2e1e",
|
|
233
|
+
tx: "#e0f0e0",
|
|
234
|
+
tx2: "#8aaa8a",
|
|
235
|
+
txM: "#6a8a6a",
|
|
236
|
+
ac: "#22c55e",
|
|
237
|
+
acD: "rgba(34,197,94,0.10)",
|
|
238
|
+
acT: "#4ade80",
|
|
239
|
+
cdBg: "#070e07",
|
|
240
|
+
cdTx: "#a0c4a0",
|
|
241
|
+
sbBg: "#091209",
|
|
242
|
+
hdBg: "rgba(9,18,9,0.90)"
|
|
243
|
+
},
|
|
244
|
+
light: {
|
|
245
|
+
bg: "#f4faf4",
|
|
246
|
+
sf: "#ffffff",
|
|
247
|
+
sfH: "#e8f4e8",
|
|
248
|
+
bd: "#c8e0c8",
|
|
249
|
+
tx: "#0a1a0a",
|
|
250
|
+
tx2: "#3a5a3a",
|
|
251
|
+
txM: "#5a7a5a",
|
|
252
|
+
ac: "#15803d",
|
|
253
|
+
acD: "rgba(21,128,61,0.07)",
|
|
254
|
+
acT: "#116d34",
|
|
255
|
+
cdBg: "#e4f2e4",
|
|
256
|
+
cdTx: "#1a3a1a",
|
|
257
|
+
sbBg: "#eef6ee",
|
|
258
|
+
hdBg: "rgba(244,250,244,0.92)"
|
|
259
|
+
},
|
|
260
|
+
fonts: { heading: "Merriweather", body: "Nunito Sans", code: "Source Code Pro" }
|
|
261
|
+
},
|
|
262
|
+
slate: {
|
|
263
|
+
dark: {
|
|
264
|
+
bg: "#0f1115",
|
|
265
|
+
sf: "#16181e",
|
|
266
|
+
sfH: "#1c1f26",
|
|
267
|
+
bd: "#24272e",
|
|
268
|
+
tx: "#e2e4e8",
|
|
269
|
+
tx2: "#9498a0",
|
|
270
|
+
txM: "#808690",
|
|
271
|
+
ac: "#94a3b8",
|
|
272
|
+
acD: "rgba(148,163,184,0.10)",
|
|
273
|
+
acT: "#b0bec8",
|
|
274
|
+
cdBg: "#0c0e12",
|
|
275
|
+
cdTx: "#a8acb4",
|
|
276
|
+
sbBg: "#0f1115",
|
|
277
|
+
hdBg: "rgba(15,17,21,0.88)"
|
|
278
|
+
},
|
|
279
|
+
light: {
|
|
280
|
+
bg: "#f8fafc",
|
|
281
|
+
sf: "#ffffff",
|
|
282
|
+
sfH: "#f1f5f9",
|
|
283
|
+
bd: "#d8dfe7",
|
|
284
|
+
tx: "#0f172a",
|
|
285
|
+
tx2: "#475569",
|
|
286
|
+
txM: "#64748b",
|
|
287
|
+
ac: "#475569",
|
|
288
|
+
acD: "rgba(71,85,105,0.07)",
|
|
289
|
+
acT: "#3a4a5c",
|
|
290
|
+
cdBg: "#f0f4f8",
|
|
291
|
+
cdTx: "#1e293b",
|
|
292
|
+
sbBg: "#f5f7fa",
|
|
293
|
+
hdBg: "rgba(248,250,252,0.92)"
|
|
294
|
+
},
|
|
295
|
+
fonts: { heading: "Inter", body: "Inter", code: "JetBrains Mono" }
|
|
296
|
+
},
|
|
297
|
+
sunset: {
|
|
298
|
+
dark: {
|
|
299
|
+
bg: "#120c06",
|
|
300
|
+
sf: "#1a1208",
|
|
301
|
+
sfH: "#22180c",
|
|
302
|
+
bd: "#2e2010",
|
|
303
|
+
tx: "#f0e4d4",
|
|
304
|
+
tx2: "#b0986a",
|
|
305
|
+
txM: "#907850",
|
|
306
|
+
ac: "#f97316",
|
|
307
|
+
acD: "rgba(249,115,22,0.10)",
|
|
308
|
+
acT: "#fb923c",
|
|
309
|
+
cdBg: "#0e0a05",
|
|
310
|
+
cdTx: "#c8aa78",
|
|
311
|
+
sbBg: "#120c06",
|
|
312
|
+
hdBg: "rgba(18,12,6,0.90)"
|
|
313
|
+
},
|
|
314
|
+
light: {
|
|
315
|
+
bg: "#fffbf5",
|
|
316
|
+
sf: "#ffffff",
|
|
317
|
+
sfH: "#fef3e6",
|
|
318
|
+
bd: "#f0d8b8",
|
|
319
|
+
tx: "#1a1008",
|
|
320
|
+
tx2: "#6a5030",
|
|
321
|
+
txM: "#8a6840",
|
|
322
|
+
ac: "#c2410c",
|
|
323
|
+
acD: "rgba(194,65,12,0.06)",
|
|
324
|
+
acT: "#a63a0a",
|
|
325
|
+
cdBg: "#faf0e2",
|
|
326
|
+
cdTx: "#3a2810",
|
|
327
|
+
sbBg: "#fdf6ec",
|
|
328
|
+
hdBg: "rgba(255,251,245,0.92)"
|
|
329
|
+
},
|
|
330
|
+
fonts: { heading: "Sora", body: "DM Sans", code: "Fira Code" }
|
|
331
|
+
},
|
|
332
|
+
carbon: {
|
|
333
|
+
dark: {
|
|
334
|
+
bg: "#080808",
|
|
335
|
+
sf: "#101010",
|
|
336
|
+
sfH: "#171717",
|
|
337
|
+
bd: "#1f1f1f",
|
|
338
|
+
tx: "#d4d4d4",
|
|
339
|
+
tx2: "#888888",
|
|
340
|
+
txM: "#787878",
|
|
341
|
+
ac: "#e4e4e4",
|
|
342
|
+
acD: "rgba(228,228,228,0.08)",
|
|
343
|
+
acT: "#f0f0f0",
|
|
344
|
+
cdBg: "#0a0a0a",
|
|
345
|
+
cdTx: "#a0a0a0",
|
|
346
|
+
sbBg: "#080808",
|
|
347
|
+
hdBg: "rgba(8,8,8,0.90)"
|
|
348
|
+
},
|
|
349
|
+
light: {
|
|
350
|
+
bg: "#f5f5f5",
|
|
351
|
+
sf: "#ffffff",
|
|
352
|
+
sfH: "#ebebeb",
|
|
353
|
+
bd: "#d4d4d4",
|
|
354
|
+
tx: "#171717",
|
|
355
|
+
tx2: "#525252",
|
|
356
|
+
txM: "#6b6b6b",
|
|
357
|
+
ac: "#262626",
|
|
358
|
+
acD: "rgba(38,38,38,0.06)",
|
|
359
|
+
acT: "#1a1a1a",
|
|
360
|
+
cdBg: "#eaeaea",
|
|
361
|
+
cdTx: "#1a1a1a",
|
|
362
|
+
sbBg: "#f0f0f0",
|
|
363
|
+
hdBg: "rgba(245,245,245,0.92)"
|
|
364
|
+
},
|
|
365
|
+
fonts: { heading: "Geist", body: "Geist", code: "Geist Mono" }
|
|
149
366
|
}
|
|
150
367
|
};
|
|
151
368
|
|
|
@@ -194,66 +411,6 @@ var SendIcon = () => /* @__PURE__ */ jsx(
|
|
|
194
411
|
children: /* @__PURE__ */ jsx("path", { d: "M22 2L11 13M22 2l-7 20-4-9-9-4z" })
|
|
195
412
|
}
|
|
196
413
|
);
|
|
197
|
-
function buildSystemPrompt(context) {
|
|
198
|
-
let prompt = "You are a helpful documentation assistant. Answer questions accurately based on the documentation provided below. If the answer isn't in the documentation, say so clearly. Keep answers concise and reference specific sections when possible.";
|
|
199
|
-
if (context) {
|
|
200
|
-
const trimmed = context.length > 1e5 ? context.slice(0, 1e5) + "\n\n[Documentation truncated...]" : context;
|
|
201
|
-
prompt += `
|
|
202
|
-
|
|
203
|
-
Documentation:
|
|
204
|
-
${trimmed}`;
|
|
205
|
-
}
|
|
206
|
-
return prompt;
|
|
207
|
-
}
|
|
208
|
-
async function callOpenAI(messages, apiKey, model, context) {
|
|
209
|
-
const res = await fetch("https://api.openai.com/v1/chat/completions", {
|
|
210
|
-
method: "POST",
|
|
211
|
-
headers: {
|
|
212
|
-
"Content-Type": "application/json",
|
|
213
|
-
"Authorization": `Bearer ${apiKey}`
|
|
214
|
-
},
|
|
215
|
-
body: JSON.stringify({
|
|
216
|
-
model,
|
|
217
|
-
messages: [
|
|
218
|
-
{ role: "system", content: buildSystemPrompt(context) },
|
|
219
|
-
...messages.map((m) => ({ role: m.role, content: m.content }))
|
|
220
|
-
]
|
|
221
|
-
})
|
|
222
|
-
});
|
|
223
|
-
if (!res.ok) {
|
|
224
|
-
const err = await res.text();
|
|
225
|
-
throw new Error(`OpenAI API error (${res.status}): ${err}`);
|
|
226
|
-
}
|
|
227
|
-
const data = await res.json();
|
|
228
|
-
return data.choices?.[0]?.message?.content || "No response.";
|
|
229
|
-
}
|
|
230
|
-
async function callAnthropic(messages, apiKey, model, context) {
|
|
231
|
-
const res = await fetch("https://api.anthropic.com/v1/messages", {
|
|
232
|
-
method: "POST",
|
|
233
|
-
headers: {
|
|
234
|
-
"Content-Type": "application/json",
|
|
235
|
-
"x-api-key": apiKey,
|
|
236
|
-
"anthropic-version": "2023-06-01",
|
|
237
|
-
"anthropic-dangerous-direct-browser-access": "true"
|
|
238
|
-
},
|
|
239
|
-
body: JSON.stringify({
|
|
240
|
-
model,
|
|
241
|
-
max_tokens: 1024,
|
|
242
|
-
system: buildSystemPrompt(context),
|
|
243
|
-
messages: messages.map((m) => ({ role: m.role, content: m.content }))
|
|
244
|
-
})
|
|
245
|
-
});
|
|
246
|
-
if (!res.ok) {
|
|
247
|
-
const err = await res.text();
|
|
248
|
-
throw new Error(`Anthropic API error (${res.status}): ${err}`);
|
|
249
|
-
}
|
|
250
|
-
const data = await res.json();
|
|
251
|
-
return data.content?.[0]?.text || "No response.";
|
|
252
|
-
}
|
|
253
|
-
function getDefaultModel(provider) {
|
|
254
|
-
if (provider === "openai") return "gpt-4o-mini";
|
|
255
|
-
return "claude-sonnet-4-20250514";
|
|
256
|
-
}
|
|
257
414
|
function AiChat({ provider, model, apiKey, context }) {
|
|
258
415
|
const [open, setOpen] = useState(false);
|
|
259
416
|
const [messages, setMessages] = useState([]);
|
|
@@ -284,10 +441,11 @@ function AiChat({ provider, model, apiKey, context }) {
|
|
|
284
441
|
setError(null);
|
|
285
442
|
try {
|
|
286
443
|
let response;
|
|
444
|
+
const sysPrompt = buildSystemPrompt(context);
|
|
287
445
|
if (provider === "openai") {
|
|
288
|
-
response = await callOpenAI(updatedMessages, resolvedKey, resolvedModel,
|
|
446
|
+
response = await callOpenAI(updatedMessages, resolvedKey, resolvedModel, sysPrompt);
|
|
289
447
|
} else {
|
|
290
|
-
response = await callAnthropic(updatedMessages, resolvedKey, resolvedModel,
|
|
448
|
+
response = await callAnthropic(updatedMessages, resolvedKey, resolvedModel, sysPrompt);
|
|
291
449
|
}
|
|
292
450
|
setMessages((prev) => [...prev, { role: "assistant", content: response }]);
|
|
293
451
|
} catch (err) {
|
|
@@ -889,10 +1047,12 @@ function Shell({
|
|
|
889
1047
|
lastUpdated,
|
|
890
1048
|
changelogEntries,
|
|
891
1049
|
apiManifest,
|
|
1050
|
+
asyncApiManifest,
|
|
892
1051
|
apiBaseUrl,
|
|
893
1052
|
apiPlayground,
|
|
894
1053
|
apiAuth,
|
|
895
1054
|
ApiReferenceComponent,
|
|
1055
|
+
AsyncApiReferenceComponent,
|
|
896
1056
|
onNavigate,
|
|
897
1057
|
allPages,
|
|
898
1058
|
versioning,
|
|
@@ -921,6 +1081,9 @@ function Shell({
|
|
|
921
1081
|
const [localeDropdownOpen, setLocaleDropdown] = useState2(false);
|
|
922
1082
|
const [zoomSrc, setZoomSrc] = useState2(null);
|
|
923
1083
|
const [feedbackGiven, setFeedbackGiven] = useState2({});
|
|
1084
|
+
const [feedbackRating, setFeedbackRating] = useState2({});
|
|
1085
|
+
const [feedbackComment, setFeedbackComment] = useState2("");
|
|
1086
|
+
const [feedbackSubmitted, setFeedbackSubmitted] = useState2({});
|
|
924
1087
|
const [bannerDismissed, setBannerDismissed] = useState2(() => {
|
|
925
1088
|
if (!config2.banner?.text) return true;
|
|
926
1089
|
try {
|
|
@@ -1192,7 +1355,14 @@ function Shell({
|
|
|
1192
1355
|
setSearch(false);
|
|
1193
1356
|
},
|
|
1194
1357
|
onClose: () => setSearch(false),
|
|
1195
|
-
mobile
|
|
1358
|
+
mobile,
|
|
1359
|
+
aiSearch: config2.search?.ai && config2.ai?.enabled ? {
|
|
1360
|
+
provider: config2.ai.provider || "anthropic",
|
|
1361
|
+
model: config2.ai.model,
|
|
1362
|
+
apiKey: window.__TOME_AI_API_KEY__ || void 0,
|
|
1363
|
+
context: docContext2?.map((d) => `## ${d.title}
|
|
1364
|
+
${d.content}`).join("\n\n")
|
|
1365
|
+
} : void 0
|
|
1196
1366
|
}
|
|
1197
1367
|
) : null,
|
|
1198
1368
|
/* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: isRtl ? "row-reverse" : "row", flex: 1, height: config2.banner?.text && !bannerDismissed ? "calc(100vh - 32px)" : "100vh" }, children: [
|
|
@@ -1349,7 +1519,7 @@ function Shell({
|
|
|
1349
1519
|
)) }),
|
|
1350
1520
|
/* @__PURE__ */ jsxs2("div", { style: { padding: "12px 16px", borderTop: "1px solid var(--bd)", display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
|
|
1351
1521
|
themeMode === "auto" ? /* @__PURE__ */ jsx2("button", { "aria-label": isDark ? "Switch to light mode" : "Switch to dark mode", onClick: () => setDark((d) => !d), style: { background: "none", border: "none", color: "var(--txM)", cursor: "pointer", display: "flex" }, children: isDark ? /* @__PURE__ */ jsx2(SunIcon, {}) : /* @__PURE__ */ jsx2(MoonIcon, {}) }) : /* @__PURE__ */ jsx2("div", {}),
|
|
1352
|
-
/* @__PURE__ */ jsxs2("span", { style: { fontSize: 11, color: "var(--txM)", letterSpacing: 0.2 }, children: [
|
|
1522
|
+
config2.branding?.powered !== false && /* @__PURE__ */ jsxs2("span", { style: { fontSize: 11, color: "var(--txM)", letterSpacing: 0.2 }, children: [
|
|
1353
1523
|
"Built with ",
|
|
1354
1524
|
"\u2661",
|
|
1355
1525
|
" by Tome"
|
|
@@ -1659,7 +1829,7 @@ function Shell({
|
|
|
1659
1829
|
}
|
|
1660
1830
|
),
|
|
1661
1831
|
/* @__PURE__ */ jsxs2("div", { ref: contentRef, style: { flex: 1, overflow: "auto", display: "flex" }, children: [
|
|
1662
|
-
/* @__PURE__ */ jsxs2("main", { style: { flex: 1, maxWidth: mobile ? "100%" : apiManifest ? 1100 : 760, padding: mobile ? "24px 16px 60px" : "40px 48px 80px", margin: "0 auto", minWidth: 0 }, children: [
|
|
1832
|
+
/* @__PURE__ */ jsxs2("main", { style: { flex: 1, maxWidth: mobile ? "100%" : apiManifest || asyncApiManifest ? 1100 : 760, padding: mobile ? "24px 16px 60px" : "40px 48px 80px", margin: "0 auto", minWidth: 0 }, children: [
|
|
1663
1833
|
breadcrumbs.length > 0 && /* @__PURE__ */ jsx2("nav", { "aria-label": "Breadcrumbs", "data-testid": "breadcrumbs", style: {
|
|
1664
1834
|
display: "flex",
|
|
1665
1835
|
alignItems: "center",
|
|
@@ -1686,7 +1856,13 @@ function Shell({
|
|
|
1686
1856
|
/* @__PURE__ */ jsx2("h1", { style: { fontFamily: "var(--font-heading)", fontSize: mobile ? 26 : 38, fontWeight: 400, fontStyle: "italic", lineHeight: 1.15, marginBottom: 8 }, children: pageTitle }),
|
|
1687
1857
|
isDraft && /* @__PURE__ */ jsx2("div", { "data-testid": "draft-banner", style: { background: "#fef3c7", color: "#92400e", padding: "8px 16px", borderRadius: 6, fontSize: 13, marginBottom: 16 }, children: "Draft \u2014 This page is only visible in development" }),
|
|
1688
1858
|
pageDescription && /* @__PURE__ */ jsx2("p", { style: { fontSize: 16, color: "var(--tx2)", lineHeight: 1.6, marginBottom: 32 }, children: pageDescription }),
|
|
1689
|
-
/* @__PURE__ */ jsx2("div", { style: { borderTop: "1px solid var(--bd)", paddingTop: 28 }, children: apiManifest && ApiReferenceComponent ? /* @__PURE__ */
|
|
1859
|
+
/* @__PURE__ */ jsx2("div", { style: { borderTop: "1px solid var(--bd)", paddingTop: 28 }, children: (apiManifest || asyncApiManifest) && (ApiReferenceComponent || AsyncApiReferenceComponent) ? /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
1860
|
+
apiManifest && ApiReferenceComponent && /* @__PURE__ */ jsx2(ApiReferenceComponent, { manifest: apiManifest, baseUrl: apiBaseUrl, showPlayground: apiPlayground, playgroundAuth: apiAuth }),
|
|
1861
|
+
asyncApiManifest && AsyncApiReferenceComponent && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
1862
|
+
apiManifest && /* @__PURE__ */ jsx2("div", { style: { borderTop: "1px solid var(--bd)", margin: "40px 0" } }),
|
|
1863
|
+
/* @__PURE__ */ jsx2(AsyncApiReferenceComponent, { manifest: asyncApiManifest })
|
|
1864
|
+
] })
|
|
1865
|
+
] }) : (
|
|
1690
1866
|
/* TOM-49: Changelog page type */
|
|
1691
1867
|
changelogEntries && changelogEntries.length > 0 ? /* @__PURE__ */ jsx2(ChangelogView, { entries: changelogEntries }) : PageComponent ? /* @__PURE__ */ jsx2("div", { className: "tome-content", children: /* @__PURE__ */ jsx2(PageComponent, { components: mdxComponents || {} }) }) : /* @__PURE__ */ jsx2(
|
|
1692
1868
|
"div",
|
|
@@ -1739,13 +1915,100 @@ function Shell({
|
|
|
1739
1915
|
formatRelativeDate(lastUpdated)
|
|
1740
1916
|
] })
|
|
1741
1917
|
] }),
|
|
1742
|
-
/* @__PURE__ */ jsx2("div", {
|
|
1918
|
+
config2.feedback?.enabled !== false && /* @__PURE__ */ jsx2("div", { "data-testid": "feedback-widget", style: { marginTop: 24, padding: "12px 0" }, children: feedbackSubmitted[currentPageId] ? /* @__PURE__ */ jsx2("span", { style: { fontSize: 13, color: "var(--txM)", fontFamily: "var(--font-body)" }, children: "Thanks for your feedback!" }) : feedbackGiven[currentPageId] && config2.feedback?.textInput ? /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "column", gap: 8 }, children: [
|
|
1919
|
+
/* @__PURE__ */ jsx2("span", { style: { fontSize: 13, color: "var(--txM)", fontFamily: "var(--font-body)" }, children: "Any additional feedback? (optional)" }),
|
|
1920
|
+
/* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: 8 }, children: [
|
|
1921
|
+
/* @__PURE__ */ jsx2(
|
|
1922
|
+
"input",
|
|
1923
|
+
{
|
|
1924
|
+
"data-testid": "feedback-text-input",
|
|
1925
|
+
type: "text",
|
|
1926
|
+
value: feedbackComment,
|
|
1927
|
+
onChange: (e) => setFeedbackComment(e.target.value),
|
|
1928
|
+
placeholder: "Tell us more...",
|
|
1929
|
+
style: {
|
|
1930
|
+
flex: 1,
|
|
1931
|
+
padding: "6px 10px",
|
|
1932
|
+
fontSize: 13,
|
|
1933
|
+
fontFamily: "var(--font-body)",
|
|
1934
|
+
background: "var(--sf)",
|
|
1935
|
+
border: "1px solid var(--bd)",
|
|
1936
|
+
borderRadius: 2,
|
|
1937
|
+
color: "var(--tx)",
|
|
1938
|
+
outline: "none"
|
|
1939
|
+
},
|
|
1940
|
+
onKeyDown: (e) => {
|
|
1941
|
+
if (e.key === "Enter") {
|
|
1942
|
+
window.__tome?.trackFeedback(currentPageId, feedbackRating[currentPageId], feedbackComment);
|
|
1943
|
+
try {
|
|
1944
|
+
localStorage.setItem(`tome-feedback-${currentPageId}`, feedbackRating[currentPageId]);
|
|
1945
|
+
} catch {
|
|
1946
|
+
}
|
|
1947
|
+
setFeedbackSubmitted((prev2) => ({ ...prev2, [currentPageId]: true }));
|
|
1948
|
+
setFeedbackComment("");
|
|
1949
|
+
}
|
|
1950
|
+
}
|
|
1951
|
+
}
|
|
1952
|
+
),
|
|
1953
|
+
/* @__PURE__ */ jsx2(
|
|
1954
|
+
"button",
|
|
1955
|
+
{
|
|
1956
|
+
"data-testid": "feedback-submit",
|
|
1957
|
+
onClick: () => {
|
|
1958
|
+
window.__tome?.trackFeedback(currentPageId, feedbackRating[currentPageId], feedbackComment);
|
|
1959
|
+
try {
|
|
1960
|
+
localStorage.setItem(`tome-feedback-${currentPageId}`, feedbackRating[currentPageId]);
|
|
1961
|
+
} catch {
|
|
1962
|
+
}
|
|
1963
|
+
setFeedbackSubmitted((prev2) => ({ ...prev2, [currentPageId]: true }));
|
|
1964
|
+
setFeedbackComment("");
|
|
1965
|
+
},
|
|
1966
|
+
style: {
|
|
1967
|
+
background: "none",
|
|
1968
|
+
border: "1px solid var(--bd)",
|
|
1969
|
+
borderRadius: 2,
|
|
1970
|
+
padding: "6px 14px",
|
|
1971
|
+
cursor: "pointer",
|
|
1972
|
+
fontSize: 13,
|
|
1973
|
+
color: "var(--txM)"
|
|
1974
|
+
},
|
|
1975
|
+
children: "Submit"
|
|
1976
|
+
}
|
|
1977
|
+
),
|
|
1978
|
+
/* @__PURE__ */ jsx2(
|
|
1979
|
+
"button",
|
|
1980
|
+
{
|
|
1981
|
+
onClick: () => {
|
|
1982
|
+
window.__tome?.trackFeedback(currentPageId, feedbackRating[currentPageId]);
|
|
1983
|
+
try {
|
|
1984
|
+
localStorage.setItem(`tome-feedback-${currentPageId}`, feedbackRating[currentPageId]);
|
|
1985
|
+
} catch {
|
|
1986
|
+
}
|
|
1987
|
+
setFeedbackSubmitted((prev2) => ({ ...prev2, [currentPageId]: true }));
|
|
1988
|
+
},
|
|
1989
|
+
style: {
|
|
1990
|
+
background: "none",
|
|
1991
|
+
border: "none",
|
|
1992
|
+
cursor: "pointer",
|
|
1993
|
+
fontSize: 13,
|
|
1994
|
+
color: "var(--txM)"
|
|
1995
|
+
},
|
|
1996
|
+
children: "Skip"
|
|
1997
|
+
}
|
|
1998
|
+
)
|
|
1999
|
+
] })
|
|
2000
|
+
] }) : feedbackGiven[currentPageId] ? /* @__PURE__ */ jsx2("span", { style: { fontSize: 13, color: "var(--txM)", fontFamily: "var(--font-body)" }, children: "Thanks for your feedback!" }) : /* @__PURE__ */ jsxs2("div", { style: { display: "flex", alignItems: "center", gap: 12 }, children: [
|
|
1743
2001
|
/* @__PURE__ */ jsx2("span", { style: { fontSize: 13, color: "var(--txM)", fontFamily: "var(--font-body)" }, children: "Was this helpful?" }),
|
|
1744
|
-
/* @__PURE__ */ jsx2("button", { onClick: () => {
|
|
2002
|
+
/* @__PURE__ */ jsx2("button", { "data-testid": "feedback-up", onClick: () => {
|
|
2003
|
+
setFeedbackRating((prev2) => ({ ...prev2, [currentPageId]: "up" }));
|
|
1745
2004
|
setFeedbackGiven((prev2) => ({ ...prev2, [currentPageId]: true }));
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
2005
|
+
if (!config2.feedback?.textInput) {
|
|
2006
|
+
window.__tome?.trackFeedback(currentPageId, "up");
|
|
2007
|
+
try {
|
|
2008
|
+
localStorage.setItem(`tome-feedback-${currentPageId}`, "up");
|
|
2009
|
+
} catch {
|
|
2010
|
+
}
|
|
2011
|
+
setFeedbackSubmitted((prev2) => ({ ...prev2, [currentPageId]: true }));
|
|
1749
2012
|
}
|
|
1750
2013
|
}, style: {
|
|
1751
2014
|
background: "none",
|
|
@@ -1757,11 +2020,16 @@ function Shell({
|
|
|
1757
2020
|
color: "var(--txM)",
|
|
1758
2021
|
transition: "border-color .15s"
|
|
1759
2022
|
}, children: "\u{1F44D}" }),
|
|
1760
|
-
/* @__PURE__ */ jsx2("button", { onClick: () => {
|
|
2023
|
+
/* @__PURE__ */ jsx2("button", { "data-testid": "feedback-down", onClick: () => {
|
|
2024
|
+
setFeedbackRating((prev2) => ({ ...prev2, [currentPageId]: "down" }));
|
|
1761
2025
|
setFeedbackGiven((prev2) => ({ ...prev2, [currentPageId]: true }));
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
2026
|
+
if (!config2.feedback?.textInput) {
|
|
2027
|
+
window.__tome?.trackFeedback(currentPageId, "down");
|
|
2028
|
+
try {
|
|
2029
|
+
localStorage.setItem(`tome-feedback-${currentPageId}`, "down");
|
|
2030
|
+
} catch {
|
|
2031
|
+
}
|
|
2032
|
+
setFeedbackSubmitted((prev2) => ({ ...prev2, [currentPageId]: true }));
|
|
1765
2033
|
}
|
|
1766
2034
|
}, style: {
|
|
1767
2035
|
background: "none",
|
|
@@ -1921,13 +2189,16 @@ ${d.content}`).join("\n\n") ?? allPages.map((p) => `- ${p.title}${p.description
|
|
|
1921
2189
|
}, children: /* @__PURE__ */ jsx2("img", { src: zoomSrc, alt: "", style: { maxWidth: "90vw", maxHeight: "90vh", objectFit: "contain", borderRadius: 4, boxShadow: "0 16px 64px rgba(0,0,0,0.4)" } }) })
|
|
1922
2190
|
] });
|
|
1923
2191
|
}
|
|
1924
|
-
function SearchModal({ allPages, onNavigate, onClose, mobile }) {
|
|
2192
|
+
function SearchModal({ allPages, onNavigate, onClose, mobile, aiSearch }) {
|
|
1925
2193
|
const [q, setQ] = useState2("");
|
|
1926
2194
|
const [results, setResults] = useState2([]);
|
|
1927
2195
|
const [selected, setSelected] = useState2(0);
|
|
1928
2196
|
const [pagefindReady, setPagefindReady] = useState2(null);
|
|
2197
|
+
const [aiAnswer, setAiAnswer] = useState2(null);
|
|
2198
|
+
const [aiLoading, setAiLoading] = useState2(false);
|
|
1929
2199
|
const inputRef = useRef2(null);
|
|
1930
2200
|
const debounceRef = useRef2(void 0);
|
|
2201
|
+
const aiDebounceRef = useRef2(void 0);
|
|
1931
2202
|
useEffect2(() => {
|
|
1932
2203
|
initPagefind().then((pf) => setPagefindReady(!!pf));
|
|
1933
2204
|
setTimeout(() => inputRef.current?.focus(), 50);
|
|
@@ -1960,12 +2231,15 @@ function SearchModal({ allPages, onNavigate, onClose, mobile }) {
|
|
|
1960
2231
|
}
|
|
1961
2232
|
setResults(items);
|
|
1962
2233
|
setSelected(0);
|
|
2234
|
+
window.__tome?.trackSearch(query, items.length);
|
|
1963
2235
|
return;
|
|
1964
2236
|
} catch {
|
|
1965
2237
|
}
|
|
1966
2238
|
}
|
|
1967
|
-
|
|
2239
|
+
const fallbackResults = fallbackSearch(query);
|
|
2240
|
+
setResults(fallbackResults);
|
|
1968
2241
|
setSelected(0);
|
|
2242
|
+
window.__tome?.trackSearch(query, fallbackResults.length);
|
|
1969
2243
|
}, [fallbackSearch]);
|
|
1970
2244
|
useEffect2(() => {
|
|
1971
2245
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
@@ -1974,6 +2248,46 @@ function SearchModal({ allPages, onNavigate, onClose, mobile }) {
|
|
|
1974
2248
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
1975
2249
|
};
|
|
1976
2250
|
}, [q, doSearch]);
|
|
2251
|
+
useEffect2(() => {
|
|
2252
|
+
if (!aiSearch?.apiKey || !q.trim() || q.length < 3) {
|
|
2253
|
+
setAiAnswer(null);
|
|
2254
|
+
return;
|
|
2255
|
+
}
|
|
2256
|
+
if (aiDebounceRef.current) clearTimeout(aiDebounceRef.current);
|
|
2257
|
+
aiDebounceRef.current = setTimeout(async () => {
|
|
2258
|
+
setAiLoading(true);
|
|
2259
|
+
try {
|
|
2260
|
+
const { callAiProvider, buildSystemPrompt: buildSystemPrompt2, getDefaultModel: getDefaultModel2 } = await import("./ai-api-6KVITVN6.js");
|
|
2261
|
+
const model = aiSearch.model || getDefaultModel2(aiSearch.provider);
|
|
2262
|
+
const searchContext = results.slice(0, 5).map((r) => `Page: ${r.title}
|
|
2263
|
+
${r.excerpt || ""}`).join("\n\n");
|
|
2264
|
+
const fullContext = aiSearch.context ? `${searchContext}
|
|
2265
|
+
|
|
2266
|
+
---
|
|
2267
|
+
|
|
2268
|
+
${aiSearch.context}` : searchContext;
|
|
2269
|
+
const sysPrompt = buildSystemPrompt2(
|
|
2270
|
+
fullContext,
|
|
2271
|
+
"You are a documentation search assistant. Answer the user's question concisely (2-3 sentences max) based on the documentation. Cite specific page names when relevant. If you can't answer from the docs, say so briefly."
|
|
2272
|
+
);
|
|
2273
|
+
const answer = await callAiProvider(
|
|
2274
|
+
aiSearch.provider,
|
|
2275
|
+
[{ role: "user", content: q }],
|
|
2276
|
+
aiSearch.apiKey || "",
|
|
2277
|
+
model,
|
|
2278
|
+
sysPrompt
|
|
2279
|
+
);
|
|
2280
|
+
setAiAnswer(answer);
|
|
2281
|
+
} catch {
|
|
2282
|
+
setAiAnswer(null);
|
|
2283
|
+
} finally {
|
|
2284
|
+
setAiLoading(false);
|
|
2285
|
+
}
|
|
2286
|
+
}, 500);
|
|
2287
|
+
return () => {
|
|
2288
|
+
if (aiDebounceRef.current) clearTimeout(aiDebounceRef.current);
|
|
2289
|
+
};
|
|
2290
|
+
}, [q, results, aiSearch]);
|
|
1977
2291
|
const handleKeyDown = useCallback2((e) => {
|
|
1978
2292
|
if (e.key === "ArrowDown") {
|
|
1979
2293
|
e.preventDefault();
|
|
@@ -2023,6 +2337,17 @@ function SearchModal({ allPages, onNavigate, onClose, mobile }) {
|
|
|
2023
2337
|
),
|
|
2024
2338
|
/* @__PURE__ */ jsx2("kbd", { style: { fontFamily: "var(--font-code)", fontSize: 10, color: "var(--txM)", background: "var(--cdBg)", padding: "2px 6px", borderRadius: 2, border: "1px solid var(--bd)" }, children: "ESC" })
|
|
2025
2339
|
] }),
|
|
2340
|
+
aiSearch && q.length >= 3 && (aiLoading || aiAnswer) && /* @__PURE__ */ jsxs2("div", { style: {
|
|
2341
|
+
padding: "12px 18px",
|
|
2342
|
+
borderBottom: "1px solid var(--bd)",
|
|
2343
|
+
background: "var(--acT)",
|
|
2344
|
+
fontSize: 13,
|
|
2345
|
+
lineHeight: 1.5,
|
|
2346
|
+
color: "var(--tx)"
|
|
2347
|
+
}, children: [
|
|
2348
|
+
/* @__PURE__ */ jsx2("div", { style: { fontSize: 10, fontWeight: 600, textTransform: "uppercase", letterSpacing: 0.5, color: "var(--ac)", marginBottom: 6 }, children: "AI Answer" }),
|
|
2349
|
+
aiLoading ? /* @__PURE__ */ jsx2("div", { style: { color: "var(--txM)", fontStyle: "italic" }, children: "Thinking..." }) : aiAnswer ? /* @__PURE__ */ jsx2("div", { children: aiAnswer }) : null
|
|
2350
|
+
] }),
|
|
2026
2351
|
results.length > 0 && /* @__PURE__ */ jsx2("div", { style: { padding: 6, maxHeight: mobile ? "none" : 360, overflow: "auto", flex: mobile ? 1 : void 0 }, children: results.map((r, i) => /* @__PURE__ */ jsxs2(
|
|
2027
2352
|
"button",
|
|
2028
2353
|
{
|
|
@@ -2059,12 +2384,17 @@ function SearchModal({ allPages, onNavigate, onClose, mobile }) {
|
|
|
2059
2384
|
// src/routing.ts
|
|
2060
2385
|
function pathnameToPageId(pathname, basePath2, routes2) {
|
|
2061
2386
|
let relative = pathname;
|
|
2062
|
-
|
|
2063
|
-
|
|
2387
|
+
const normalizedBase = basePath2 === "/" ? "" : basePath2.replace(/\/+$/, "");
|
|
2388
|
+
if (normalizedBase && relative.startsWith(normalizedBase)) {
|
|
2389
|
+
relative = relative.slice(normalizedBase.length);
|
|
2064
2390
|
}
|
|
2065
2391
|
const id = relative.replace(/^\//, "").replace(/\/index\.html$/, "").replace(/\.html$/, "").replace(/\/$/, "") || "index";
|
|
2066
|
-
const
|
|
2067
|
-
|
|
2392
|
+
const routeById = routes2.find((r) => r.id === id);
|
|
2393
|
+
if (routeById) return id;
|
|
2394
|
+
const urlPath = "/" + id;
|
|
2395
|
+
const urlPathWithSlash = urlPath + "/";
|
|
2396
|
+
const routeByUrl = routes2.find((r) => r.urlPath === urlPath || r.urlPath === urlPathWithSlash);
|
|
2397
|
+
return routeByUrl ? routeByUrl.id : null;
|
|
2068
2398
|
}
|
|
2069
2399
|
function pageIdToPath(id, basePath2, routes2) {
|
|
2070
2400
|
const route = routes2.find((r) => r.id === id);
|
|
@@ -2118,8 +2448,14 @@ async function loadPage(id, routes2, loadPageModule2) {
|
|
|
2118
2448
|
};
|
|
2119
2449
|
}
|
|
2120
2450
|
if (!mod.default) throw new PageNotFoundError(id);
|
|
2121
|
-
if (mod.isApiReference && mod.apiManifest) {
|
|
2122
|
-
return {
|
|
2451
|
+
if (mod.isApiReference && (mod.apiManifest || mod.asyncApiManifest)) {
|
|
2452
|
+
return {
|
|
2453
|
+
isMdx: false,
|
|
2454
|
+
isApiReference: true,
|
|
2455
|
+
...mod.default,
|
|
2456
|
+
apiManifest: mod.apiManifest,
|
|
2457
|
+
asyncApiManifest: mod.asyncApiManifest
|
|
2458
|
+
};
|
|
2123
2459
|
}
|
|
2124
2460
|
if (mod.isChangelog && mod.changelogEntries) {
|
|
2125
2461
|
return { isMdx: false, ...mod.default, changelogEntries: mod.changelogEntries };
|
|
@@ -2150,7 +2486,8 @@ import {
|
|
|
2150
2486
|
CodeSamples,
|
|
2151
2487
|
LinkCard,
|
|
2152
2488
|
CardGrid,
|
|
2153
|
-
ApiReference
|
|
2489
|
+
ApiReference,
|
|
2490
|
+
AsyncApiReference
|
|
2154
2491
|
} from "@tomehq/components";
|
|
2155
2492
|
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
2156
2493
|
var MDX_COMPONENTS = {
|
|
@@ -2640,10 +2977,12 @@ function App() {
|
|
|
2640
2977
|
lastUpdated: currentRoute?.lastUpdated,
|
|
2641
2978
|
changelogEntries: !pageData?.isMdx ? pageData?.changelogEntries : void 0,
|
|
2642
2979
|
apiManifest: !pageData?.isMdx && pageData?.isApiReference ? pageData.apiManifest : void 0,
|
|
2980
|
+
asyncApiManifest: !pageData?.isMdx && pageData?.isApiReference ? pageData.asyncApiManifest : void 0,
|
|
2643
2981
|
apiBaseUrl: config.api?.baseUrl,
|
|
2644
2982
|
apiPlayground: config.api?.playground,
|
|
2645
2983
|
apiAuth: config.api?.auth,
|
|
2646
2984
|
ApiReferenceComponent: ApiReference,
|
|
2985
|
+
AsyncApiReferenceComponent: AsyncApiReference,
|
|
2647
2986
|
onNavigate: navigateTo,
|
|
2648
2987
|
allPages,
|
|
2649
2988
|
docContext,
|