glitchgrab 1.33.0 → 1.35.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/index.mjs CHANGED
@@ -4,11 +4,11 @@
4
4
  import {
5
5
  createContext,
6
6
  useContext,
7
- useRef as useRef3,
8
- useEffect as useEffect3,
9
- useCallback,
10
- useMemo,
11
- useState as useState3
7
+ useRef as useRef4,
8
+ useEffect as useEffect5,
9
+ useCallback as useCallback2,
10
+ useMemo as useMemo2,
11
+ useState as useState5
12
12
  } from "react";
13
13
 
14
14
  // src/error-boundary.tsx
@@ -587,6 +587,43 @@ async function enhanceText(text, token, baseUrl, screenshot, context) {
587
587
  return text;
588
588
  }
589
589
  }
590
+ async function assistTurn(params, token, baseUrl) {
591
+ var _a, _b, _c, _d, _e, _f, _g;
592
+ const offline = {
593
+ conversationId: null,
594
+ question: null,
595
+ report: null,
596
+ degraded: "The assistant is unavailable \u2014 write your report below and send it as normal."
597
+ };
598
+ try {
599
+ const url = `${baseUrl != null ? baseUrl : DEFAULT_BASE_URL}/api/v1/ai/report-chat`;
600
+ const response = await fetch(url, {
601
+ method: "POST",
602
+ headers: {
603
+ "Content-Type": "application/json",
604
+ Authorization: `Bearer ${token}`
605
+ },
606
+ body: JSON.stringify(params)
607
+ });
608
+ const envelope = await response.json().catch(() => null);
609
+ if (!response.ok || !(envelope == null ? void 0 : envelope.success)) {
610
+ return {
611
+ conversationId: null,
612
+ question: null,
613
+ report: null,
614
+ degraded: (_a = envelope == null ? void 0 : envelope.error) != null ? _a : offline.degraded
615
+ };
616
+ }
617
+ return {
618
+ conversationId: (_c = (_b = envelope.data) == null ? void 0 : _b.conversationId) != null ? _c : null,
619
+ question: (_e = (_d = envelope.data) == null ? void 0 : _d.question) != null ? _e : null,
620
+ report: (_g = (_f = envelope.data) == null ? void 0 : _f.report) != null ? _g : null,
621
+ degraded: null
622
+ };
623
+ } catch (e) {
624
+ return offline;
625
+ }
626
+ }
590
627
  async function transcribeAudio(blob, token, baseUrl) {
591
628
  var _a;
592
629
  try {
@@ -630,9 +667,9 @@ function topStackFrame(stack) {
630
667
  if (!stack) return "";
631
668
  const lines = stack.split("\n");
632
669
  for (const line of lines) {
633
- const t = line.trim();
634
- if (t.startsWith("at ") || t.includes("@")) {
635
- return t;
670
+ const t2 = line.trim();
671
+ if (t2.startsWith("at ") || t2.includes("@")) {
672
+ return t2;
636
673
  }
637
674
  }
638
675
  return "";
@@ -795,14 +832,17 @@ var GlitchgrabErrorBoundary = class extends React.Component {
795
832
 
796
833
  // ../report-ui/dist/index.mjs
797
834
  import {
798
- useState as useState2,
799
- useRef as useRef2,
800
- useEffect as useEffect2
835
+ useState as useState3,
836
+ useRef as useRef3,
837
+ useEffect as useEffect3
801
838
  } from "react";
802
- import { createPortal } from "react-dom";
839
+ import { createPortal as createPortal2 } from "react-dom";
803
840
  import { useEffect, useRef, useState } from "react";
804
841
  import { jsx, jsxs } from "react/jsx-runtime";
842
+ import { useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
843
+ import { createPortal } from "react-dom";
805
844
  import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
845
+ import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
806
846
  var MAX_SCREENSHOT_DATA_URL_LENGTH = 18e5;
807
847
  var QUALITY_LADDER = [0.92, 0.85, 0.75];
808
848
  var DOWNSCALE_FACTOR = 0.7;
@@ -1108,6 +1148,693 @@ function AnnotationCanvas({ imageSrc, onSave, onCancel }) {
1108
1148
  }
1109
1149
  );
1110
1150
  }
1151
+ var STARTERS = [
1152
+ "Something on this page is broken",
1153
+ "It did the wrong thing",
1154
+ "I wish it could\u2026"
1155
+ ];
1156
+ var NARROW_QUERY = "(max-width: 640px)";
1157
+ function useIsNarrow() {
1158
+ const [narrow, setNarrow] = useState2(false);
1159
+ useEffect2(() => {
1160
+ try {
1161
+ const mq = window.matchMedia(NARROW_QUERY);
1162
+ setNarrow(mq.matches);
1163
+ const onChange = (e) => setNarrow(e.matches);
1164
+ mq.addEventListener("change", onChange);
1165
+ return () => mq.removeEventListener("change", onChange);
1166
+ } catch (e) {
1167
+ }
1168
+ }, []);
1169
+ return narrow;
1170
+ }
1171
+ function Sparkle({ color, size = 14 }) {
1172
+ return /* @__PURE__ */ jsx2("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx2(
1173
+ "path",
1174
+ {
1175
+ d: "M12 3l1.5 4.5L18 9l-4.5 1.5L12 15l-1.5-4.5L6 9l4.5-1.5L12 3zM19 15l.75 2.25L22 18l-2.25.75L19 21l-.75-2.25L16 18l2.25-.75L19 15z",
1176
+ stroke: color,
1177
+ strokeWidth: "1.5",
1178
+ strokeLinejoin: "round"
1179
+ }
1180
+ ) });
1181
+ }
1182
+ function Avatar({
1183
+ who,
1184
+ theme: t2,
1185
+ initials
1186
+ }) {
1187
+ const isAi = who === "assistant";
1188
+ return /* @__PURE__ */ jsx2(
1189
+ "span",
1190
+ {
1191
+ "aria-hidden": "true",
1192
+ style: {
1193
+ flexShrink: 0,
1194
+ width: "24px",
1195
+ height: "24px",
1196
+ borderRadius: "50%",
1197
+ display: "inline-flex",
1198
+ alignItems: "center",
1199
+ justifyContent: "center",
1200
+ marginTop: "2px",
1201
+ backgroundColor: isAi ? `${t2.accent}22` : t2.bgSecondary,
1202
+ border: `1px solid ${isAi ? t2.accent : t2.inputBorder}`,
1203
+ color: isAi ? t2.accent : t2.textMuted,
1204
+ fontSize: "10px",
1205
+ fontWeight: 700
1206
+ },
1207
+ children: isAi ? /* @__PURE__ */ jsx2(Sparkle, { color: t2.accent, size: 12 }) : initials ? initials : /* @__PURE__ */ jsxs2("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: [
1208
+ /* @__PURE__ */ jsx2("circle", { cx: "12", cy: "8", r: "3.4", stroke: "currentColor", strokeWidth: "1.8" }),
1209
+ /* @__PURE__ */ jsx2(
1210
+ "path",
1211
+ {
1212
+ d: "M5 20c0-3.6 3.1-5.6 7-5.6s7 2 7 5.6",
1213
+ stroke: "currentColor",
1214
+ strokeWidth: "1.8",
1215
+ strokeLinecap: "round"
1216
+ }
1217
+ )
1218
+ ] })
1219
+ }
1220
+ );
1221
+ }
1222
+ function AssistSheet({
1223
+ assist,
1224
+ theme: t2,
1225
+ screenshot,
1226
+ attachmentCount,
1227
+ context,
1228
+ reportTypeLabel,
1229
+ projectSlot,
1230
+ reporterName,
1231
+ description,
1232
+ onDescriptionChange,
1233
+ severity,
1234
+ onSeverityChange,
1235
+ showSeverity,
1236
+ isSubmitting,
1237
+ submitted,
1238
+ onSend,
1239
+ onDegrade,
1240
+ onClose
1241
+ }) {
1242
+ const narrow = useIsNarrow();
1243
+ const [messages, setMessages] = useState2([]);
1244
+ const [input, setInput] = useState2("");
1245
+ const [busy, setBusy] = useState2(false);
1246
+ const [conversationId, setConversationId] = useState2(null);
1247
+ const [phase, setPhase] = useState2("chat");
1248
+ const scrollRef = useRef2(null);
1249
+ const inputRef = useRef2(null);
1250
+ const draftRef = useRef2(null);
1251
+ const seededRef = useRef2(false);
1252
+ useEffect2(() => {
1253
+ const el = scrollRef.current;
1254
+ if (el) el.scrollTop = el.scrollHeight;
1255
+ }, [messages, busy, phase]);
1256
+ useEffect2(() => {
1257
+ var _a;
1258
+ if (phase === "draft") (_a = draftRef.current) == null ? void 0 : _a.focus();
1259
+ }, [phase]);
1260
+ async function runTurn(history2) {
1261
+ setBusy(true);
1262
+ let result;
1263
+ try {
1264
+ result = await assist({ messages: history2, conversationId, screenshot, context });
1265
+ } catch (e) {
1266
+ onDegrade("The assistant is unavailable \u2014 write your report below and send it as normal.");
1267
+ return;
1268
+ } finally {
1269
+ setBusy(false);
1270
+ }
1271
+ if (result.degraded) {
1272
+ onDegrade(result.degraded);
1273
+ return;
1274
+ }
1275
+ if (result.conversationId) setConversationId(result.conversationId);
1276
+ if (result.report) {
1277
+ onDescriptionChange(result.report);
1278
+ setMessages([...history2, { role: "assistant", content: "Here's your report \u2014 have a read." }]);
1279
+ setPhase("draft");
1280
+ return;
1281
+ }
1282
+ if (result.question) {
1283
+ setMessages([...history2, { role: "assistant", content: result.question }]);
1284
+ return;
1285
+ }
1286
+ onDegrade("The assistant had nothing to add \u2014 write your report below and send it as normal.");
1287
+ }
1288
+ useEffect2(() => {
1289
+ if (seededRef.current) return;
1290
+ seededRef.current = true;
1291
+ const seed = description.trim();
1292
+ if (!seed) return;
1293
+ const history2 = [{ role: "user", content: seed }];
1294
+ setMessages(history2);
1295
+ void runTurn(history2);
1296
+ }, []);
1297
+ function send(text) {
1298
+ const value = text.trim();
1299
+ if (!value || busy) return;
1300
+ const history2 = [...messages, { role: "user", content: value }];
1301
+ setMessages(history2);
1302
+ setInput("");
1303
+ void runTurn(history2);
1304
+ }
1305
+ const empty = messages.length === 0 && !busy;
1306
+ const initials = (reporterName != null ? reporterName : "").split(/\s+/).filter(Boolean).slice(0, 2).map((w) => {
1307
+ var _a, _b;
1308
+ return (_b = (_a = w[0]) == null ? void 0 : _a.toUpperCase()) != null ? _b : "";
1309
+ }).join("");
1310
+ const panelStyle = narrow ? {
1311
+ width: "100%",
1312
+ maxHeight: "88dvh",
1313
+ borderTopLeftRadius: "16px",
1314
+ borderTopRightRadius: "16px",
1315
+ animation: "gg-sheet-up .22s cubic-bezier(.2,.8,.2,1)"
1316
+ } : {
1317
+ width: "440px",
1318
+ maxWidth: "100%",
1319
+ height: "100dvh",
1320
+ borderLeft: `1px solid ${t2.border}`,
1321
+ animation: "gg-sheet-in .22s cubic-bezier(.2,.8,.2,1)"
1322
+ };
1323
+ return createPortal(
1324
+ /* @__PURE__ */ jsxs2(Fragment, { children: [
1325
+ /* @__PURE__ */ jsx2("style", { children: `
1326
+ @keyframes gg-sheet-in{from{transform:translateX(24px);opacity:0}to{transform:translateX(0);opacity:1}}
1327
+ @keyframes gg-sheet-up{from{transform:translateY(24px);opacity:0}to{transform:translateY(0);opacity:1}}
1328
+ @keyframes gg-sheet-fade{from{opacity:0}to{opacity:1}}
1329
+ @keyframes gg-dot{0%,80%,100%{transform:translateY(0);opacity:.4}40%{transform:translateY(-3px);opacity:1}}
1330
+ [data-gg-sheet-send]:focus-visible,[data-gg-chip]:focus-visible{outline:2px solid currentColor;outline-offset:2px}
1331
+ ` }),
1332
+ /* @__PURE__ */ jsx2(
1333
+ "div",
1334
+ {
1335
+ "data-glitchgrab-layer": "",
1336
+ role: "dialog",
1337
+ "aria-modal": "true",
1338
+ "aria-label": "Describe your report with AI",
1339
+ style: {
1340
+ position: "fixed",
1341
+ inset: 0,
1342
+ zIndex: 2147483647,
1343
+ display: "flex",
1344
+ alignItems: narrow ? "flex-end" : "stretch",
1345
+ justifyContent: narrow ? "center" : "flex-end",
1346
+ backgroundColor: "rgba(0,0,0,0.5)",
1347
+ animation: "gg-sheet-fade .18s ease",
1348
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
1349
+ },
1350
+ onClick: onClose,
1351
+ onPointerDown: (e) => e.stopPropagation(),
1352
+ children: /* @__PURE__ */ jsxs2(
1353
+ "div",
1354
+ {
1355
+ onClick: (e) => e.stopPropagation(),
1356
+ style: {
1357
+ ...panelStyle,
1358
+ display: "flex",
1359
+ flexDirection: "column",
1360
+ // A flex child defaults to min-width:auto, so a long chat bubble
1361
+ // grows the sheet past the viewport instead of wrapping inside it.
1362
+ // This is what keeps the bottom sheet on screen.
1363
+ minWidth: 0,
1364
+ maxWidth: "100%",
1365
+ boxSizing: "border-box",
1366
+ backgroundColor: t2.bg,
1367
+ color: t2.text,
1368
+ boxShadow: "0 20px 60px rgba(0,0,0,.35)",
1369
+ overflow: "hidden",
1370
+ isolation: "isolate"
1371
+ },
1372
+ children: [
1373
+ /* @__PURE__ */ jsxs2(
1374
+ "div",
1375
+ {
1376
+ style: {
1377
+ flexShrink: 0,
1378
+ padding: "14px 16px",
1379
+ borderBottom: `1px solid ${t2.border}`,
1380
+ display: "flex",
1381
+ alignItems: "flex-start",
1382
+ justifyContent: "space-between",
1383
+ gap: "12px",
1384
+ minWidth: 0
1385
+ },
1386
+ children: [
1387
+ /* @__PURE__ */ jsxs2("div", { style: { minWidth: 0, overflow: "hidden" }, children: [
1388
+ /* @__PURE__ */ jsxs2(
1389
+ "div",
1390
+ {
1391
+ style: {
1392
+ display: "flex",
1393
+ alignItems: "center",
1394
+ gap: "7px",
1395
+ fontSize: "14px",
1396
+ fontWeight: 600
1397
+ },
1398
+ children: [
1399
+ /* @__PURE__ */ jsx2(Sparkle, { color: t2.accent }),
1400
+ "Describe it with AI",
1401
+ /* @__PURE__ */ jsx2(
1402
+ "span",
1403
+ {
1404
+ style: {
1405
+ fontSize: "10px",
1406
+ fontWeight: 600,
1407
+ letterSpacing: ".04em",
1408
+ textTransform: "uppercase",
1409
+ color: t2.accent,
1410
+ border: `1px solid ${t2.accent}55`,
1411
+ borderRadius: "4px",
1412
+ padding: "1px 5px"
1413
+ },
1414
+ children: "Beta"
1415
+ }
1416
+ )
1417
+ ]
1418
+ }
1419
+ ),
1420
+ /* @__PURE__ */ jsxs2("div", { style: { fontSize: "11.5px", color: t2.textMuted, marginTop: "3px" }, children: [
1421
+ reportTypeLabel,
1422
+ projectSlot ? /* @__PURE__ */ jsx2("span", { style: { marginLeft: "6px" }, children: projectSlot }) : null
1423
+ ] })
1424
+ ] }),
1425
+ /* @__PURE__ */ jsx2(
1426
+ "button",
1427
+ {
1428
+ type: "button",
1429
+ onClick: onClose,
1430
+ "aria-label": "Close and write it myself",
1431
+ style: {
1432
+ flexShrink: 0,
1433
+ border: "none",
1434
+ background: "transparent",
1435
+ color: t2.textMuted,
1436
+ cursor: "pointer",
1437
+ fontSize: narrow ? "18px" : "12px",
1438
+ lineHeight: 1,
1439
+ fontFamily: "inherit",
1440
+ padding: narrow ? "4px 6px" : "6px 4px"
1441
+ },
1442
+ children: narrow ? "\xD7" : "Write it myself"
1443
+ }
1444
+ )
1445
+ ]
1446
+ }
1447
+ ),
1448
+ /* @__PURE__ */ jsx2(
1449
+ "div",
1450
+ {
1451
+ ref: scrollRef,
1452
+ style: {
1453
+ flex: 1,
1454
+ minHeight: narrow ? "180px" : 0,
1455
+ overflowY: "auto",
1456
+ padding: "16px",
1457
+ display: "flex",
1458
+ flexDirection: "column"
1459
+ },
1460
+ children: /* @__PURE__ */ jsxs2(
1461
+ "div",
1462
+ {
1463
+ style: {
1464
+ marginTop: "auto",
1465
+ display: "flex",
1466
+ flexDirection: "column",
1467
+ gap: "12px",
1468
+ minWidth: 0
1469
+ },
1470
+ children: [
1471
+ empty && /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
1472
+ /* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "8px" }, children: [
1473
+ /* @__PURE__ */ jsx2(Avatar, { who: "assistant", theme: t2 }),
1474
+ /* @__PURE__ */ jsxs2(
1475
+ "div",
1476
+ {
1477
+ style: {
1478
+ padding: "9px 12px",
1479
+ borderRadius: "12px 12px 12px 4px",
1480
+ backgroundColor: t2.bgSecondary,
1481
+ fontSize: "13px",
1482
+ lineHeight: 1.55,
1483
+ maxWidth: "88%"
1484
+ },
1485
+ children: [
1486
+ reporterName ? `Hi ${reporterName.split(" ")[0]} \u2014 t` : "T",
1487
+ "ell me what went wrong in your own words. I can already see your screenshot and what you clicked, so skip the boring parts."
1488
+ ]
1489
+ }
1490
+ )
1491
+ ] }),
1492
+ /* @__PURE__ */ jsx2(
1493
+ "div",
1494
+ {
1495
+ style: {
1496
+ display: "flex",
1497
+ flexWrap: "wrap",
1498
+ gap: "6px",
1499
+ paddingLeft: "32px"
1500
+ },
1501
+ children: STARTERS.map((s) => /* @__PURE__ */ jsx2(
1502
+ "button",
1503
+ {
1504
+ type: "button",
1505
+ "data-gg-chip": "",
1506
+ onClick: () => send(s),
1507
+ style: {
1508
+ border: `1px solid ${t2.inputBorder}`,
1509
+ background: "transparent",
1510
+ color: t2.textMuted,
1511
+ borderRadius: "999px",
1512
+ padding: "6px 11px",
1513
+ fontSize: "12px",
1514
+ fontFamily: "inherit",
1515
+ cursor: "pointer"
1516
+ },
1517
+ children: s
1518
+ },
1519
+ s
1520
+ ))
1521
+ }
1522
+ )
1523
+ ] }),
1524
+ messages.map((m, i) => {
1525
+ const mine = m.role === "user";
1526
+ return /* @__PURE__ */ jsxs2(
1527
+ "div",
1528
+ {
1529
+ style: {
1530
+ display: "flex",
1531
+ gap: "8px",
1532
+ minWidth: 0,
1533
+ flexDirection: mine ? "row-reverse" : "row"
1534
+ },
1535
+ children: [
1536
+ /* @__PURE__ */ jsx2(Avatar, { who: m.role, theme: t2, initials }),
1537
+ /* @__PURE__ */ jsx2(
1538
+ "div",
1539
+ {
1540
+ style: {
1541
+ maxWidth: "82%",
1542
+ padding: "9px 12px",
1543
+ borderRadius: mine ? "12px 12px 4px 12px" : "12px 12px 12px 4px",
1544
+ fontSize: "13px",
1545
+ lineHeight: 1.55,
1546
+ whiteSpace: "pre-wrap",
1547
+ wordBreak: "break-word",
1548
+ backgroundColor: mine ? t2.accent : t2.bgSecondary,
1549
+ color: mine ? t2.accentText : t2.text
1550
+ },
1551
+ children: m.content
1552
+ }
1553
+ )
1554
+ ]
1555
+ },
1556
+ i
1557
+ );
1558
+ }),
1559
+ busy && /* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "8px" }, role: "status", "aria-label": "Thinking", children: [
1560
+ /* @__PURE__ */ jsx2(Avatar, { who: "assistant", theme: t2 }),
1561
+ /* @__PURE__ */ jsx2(
1562
+ "span",
1563
+ {
1564
+ style: {
1565
+ display: "inline-flex",
1566
+ alignItems: "center",
1567
+ gap: "4px",
1568
+ padding: "12px",
1569
+ borderRadius: "12px 12px 12px 4px",
1570
+ backgroundColor: t2.bgSecondary
1571
+ },
1572
+ children: [0, 1, 2].map((i) => /* @__PURE__ */ jsx2(
1573
+ "span",
1574
+ {
1575
+ style: {
1576
+ width: "5px",
1577
+ height: "5px",
1578
+ borderRadius: "50%",
1579
+ backgroundColor: t2.textMuted,
1580
+ animation: `gg-dot 1.1s ease-in-out ${i * 0.15}s infinite`
1581
+ }
1582
+ },
1583
+ i
1584
+ ))
1585
+ }
1586
+ )
1587
+ ] }),
1588
+ phase === "draft" && !submitted && /* @__PURE__ */ jsxs2(
1589
+ "div",
1590
+ {
1591
+ style: {
1592
+ border: `1px solid ${t2.accent}`,
1593
+ borderRadius: "12px",
1594
+ backgroundColor: t2.bgSecondary,
1595
+ padding: "12px",
1596
+ display: "flex",
1597
+ flexDirection: "column",
1598
+ gap: "10px",
1599
+ minWidth: 0,
1600
+ boxSizing: "border-box"
1601
+ },
1602
+ children: [
1603
+ /* @__PURE__ */ jsx2(
1604
+ "span",
1605
+ {
1606
+ style: {
1607
+ fontSize: "10px",
1608
+ fontWeight: 700,
1609
+ letterSpacing: ".06em",
1610
+ textTransform: "uppercase",
1611
+ color: t2.accent
1612
+ },
1613
+ children: "Your report \xB7 edit anything"
1614
+ }
1615
+ ),
1616
+ /* @__PURE__ */ jsx2(
1617
+ "textarea",
1618
+ {
1619
+ ref: draftRef,
1620
+ value: description,
1621
+ onChange: (e) => onDescriptionChange(e.target.value),
1622
+ rows: 6,
1623
+ style: {
1624
+ width: "100%",
1625
+ minHeight: "120px",
1626
+ padding: "10px",
1627
+ borderRadius: "8px",
1628
+ border: `1px solid ${t2.inputBorder}`,
1629
+ backgroundColor: t2.inputBg,
1630
+ color: t2.text,
1631
+ fontSize: "13px",
1632
+ lineHeight: 1.55,
1633
+ fontFamily: "inherit",
1634
+ resize: "vertical",
1635
+ outline: "none",
1636
+ boxSizing: "border-box"
1637
+ }
1638
+ }
1639
+ ),
1640
+ showSeverity && /* @__PURE__ */ jsxs2("div", { children: [
1641
+ /* @__PURE__ */ jsx2(
1642
+ "span",
1643
+ {
1644
+ style: {
1645
+ fontSize: "11.5px",
1646
+ color: t2.textMuted,
1647
+ display: "block",
1648
+ marginBottom: "6px"
1649
+ },
1650
+ children: "How bad is it?"
1651
+ }
1652
+ ),
1653
+ /* @__PURE__ */ jsx2("div", { style: { display: "flex", gap: "6px" }, children: ["low", "medium", "high"].map((s) => {
1654
+ const on = severity === s;
1655
+ return /* @__PURE__ */ jsx2(
1656
+ "button",
1657
+ {
1658
+ type: "button",
1659
+ onClick: () => onSeverityChange(s),
1660
+ "aria-pressed": on,
1661
+ style: {
1662
+ flex: 1,
1663
+ minWidth: 0,
1664
+ padding: "8px 0",
1665
+ borderRadius: "8px",
1666
+ border: `1px solid ${on ? t2.accent : t2.inputBorder}`,
1667
+ backgroundColor: on ? t2.accent : "transparent",
1668
+ color: on ? t2.accentText : t2.textMuted,
1669
+ fontSize: "12px",
1670
+ fontWeight: 600,
1671
+ fontFamily: "inherit",
1672
+ textTransform: "capitalize",
1673
+ cursor: "pointer"
1674
+ },
1675
+ children: s
1676
+ },
1677
+ s
1678
+ );
1679
+ }) })
1680
+ ] }),
1681
+ attachmentCount > 0 && /* @__PURE__ */ jsxs2("span", { style: { fontSize: "11.5px", color: t2.textMuted }, children: [
1682
+ attachmentCount,
1683
+ " ",
1684
+ attachmentCount === 1 ? "attachment" : "attachments",
1685
+ " will be sent with this."
1686
+ ] }),
1687
+ /* @__PURE__ */ jsx2(
1688
+ "button",
1689
+ {
1690
+ type: "button",
1691
+ onClick: () => setPhase("chat"),
1692
+ style: {
1693
+ alignSelf: "flex-start",
1694
+ border: "none",
1695
+ background: "transparent",
1696
+ color: t2.textMuted,
1697
+ fontSize: "12px",
1698
+ fontFamily: "inherit",
1699
+ padding: 0,
1700
+ cursor: "pointer",
1701
+ textDecoration: "underline"
1702
+ },
1703
+ children: "Not quite \u2014 keep chatting"
1704
+ }
1705
+ )
1706
+ ]
1707
+ }
1708
+ ),
1709
+ submitted && /* @__PURE__ */ jsxs2(
1710
+ "div",
1711
+ {
1712
+ style: {
1713
+ textAlign: "center",
1714
+ padding: "24px 0",
1715
+ color: t2.accent,
1716
+ fontSize: "14px",
1717
+ fontWeight: 600
1718
+ },
1719
+ children: [
1720
+ reportTypeLabel,
1721
+ " sent. Thank you!"
1722
+ ]
1723
+ }
1724
+ )
1725
+ ]
1726
+ }
1727
+ )
1728
+ }
1729
+ ),
1730
+ !submitted && /* @__PURE__ */ jsx2(
1731
+ "div",
1732
+ {
1733
+ style: {
1734
+ flexShrink: 0,
1735
+ borderTop: `1px solid ${t2.border}`,
1736
+ padding: "12px 16px",
1737
+ paddingBottom: narrow ? "max(12px, env(safe-area-inset-bottom))" : "12px",
1738
+ backgroundColor: t2.bg
1739
+ },
1740
+ children: phase === "draft" ? /* @__PURE__ */ jsx2(
1741
+ "button",
1742
+ {
1743
+ type: "button",
1744
+ "data-gg-sheet-send": "",
1745
+ onClick: onSend,
1746
+ disabled: isSubmitting || !description.trim(),
1747
+ style: {
1748
+ width: "100%",
1749
+ padding: "12px",
1750
+ borderRadius: "10px",
1751
+ border: "none",
1752
+ backgroundColor: isSubmitting || !description.trim() ? t2.bgSecondary : t2.accent,
1753
+ color: isSubmitting || !description.trim() ? t2.textMuted : t2.accentText,
1754
+ fontSize: "14px",
1755
+ fontWeight: 700,
1756
+ fontFamily: "inherit",
1757
+ cursor: isSubmitting || !description.trim() ? "default" : "pointer"
1758
+ },
1759
+ children: isSubmitting ? "Sending\u2026" : "Send Report"
1760
+ }
1761
+ ) : /* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "8px", alignItems: "flex-end" }, children: [
1762
+ /* @__PURE__ */ jsx2(
1763
+ "textarea",
1764
+ {
1765
+ ref: inputRef,
1766
+ value: input,
1767
+ onChange: (e) => setInput(e.target.value),
1768
+ onKeyDown: (e) => {
1769
+ if (e.key === "Enter" && !e.shiftKey) {
1770
+ e.preventDefault();
1771
+ send(input);
1772
+ }
1773
+ },
1774
+ placeholder: "Type your answer\u2026",
1775
+ rows: 1,
1776
+ disabled: busy,
1777
+ autoFocus: true,
1778
+ style: {
1779
+ flex: 1,
1780
+ minHeight: "42px",
1781
+ maxHeight: "120px",
1782
+ padding: "11px 12px",
1783
+ borderRadius: "10px",
1784
+ border: `1px solid ${t2.inputBorder}`,
1785
+ backgroundColor: t2.inputBg,
1786
+ color: t2.text,
1787
+ fontSize: "13px",
1788
+ lineHeight: 1.4,
1789
+ fontFamily: "inherit",
1790
+ resize: "none",
1791
+ outline: "none",
1792
+ boxSizing: "border-box"
1793
+ }
1794
+ }
1795
+ ),
1796
+ /* @__PURE__ */ jsx2(
1797
+ "button",
1798
+ {
1799
+ type: "button",
1800
+ "data-gg-sheet-send": "",
1801
+ onClick: () => send(input),
1802
+ disabled: busy || !input.trim(),
1803
+ "aria-label": "Send message",
1804
+ style: {
1805
+ flexShrink: 0,
1806
+ width: "42px",
1807
+ height: "42px",
1808
+ borderRadius: "10px",
1809
+ border: "none",
1810
+ display: "inline-flex",
1811
+ alignItems: "center",
1812
+ justifyContent: "center",
1813
+ backgroundColor: busy || !input.trim() ? t2.bgSecondary : t2.accent,
1814
+ color: busy || !input.trim() ? t2.textMuted : t2.accentText,
1815
+ cursor: busy || !input.trim() ? "default" : "pointer"
1816
+ },
1817
+ children: /* @__PURE__ */ jsx2("svg", { width: "17", height: "17", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx2(
1818
+ "path",
1819
+ {
1820
+ d: "M3 20.5L21.5 12 3 3.5V10l12 2-12 2v6.5z",
1821
+ fill: "currentColor"
1822
+ }
1823
+ ) })
1824
+ }
1825
+ )
1826
+ ] })
1827
+ }
1828
+ )
1829
+ ]
1830
+ }
1831
+ )
1832
+ }
1833
+ )
1834
+ ] }),
1835
+ document.body
1836
+ );
1837
+ }
1111
1838
  var GLITCHGRAB_SHORTCUT = "Ctrl+Shift+G";
1112
1839
  var GLITCHGRAB_SHORTCUT_MAC = "\u2318\u21E7G";
1113
1840
  function isMac() {
@@ -1273,12 +2000,12 @@ function initialsOf(name) {
1273
2000
  }
1274
2001
  function ReporterChip({
1275
2002
  reporter,
1276
- t
2003
+ t: t2
1277
2004
  }) {
1278
2005
  var _a;
1279
- const [avatarFailed, setAvatarFailed] = useState2(false);
2006
+ const [avatarFailed, setAvatarFailed] = useState3(false);
1280
2007
  const avatarUrl = (reporter == null ? void 0 : reporter.avatarUrl) || "";
1281
- useEffect2(() => {
2008
+ useEffect3(() => {
1282
2009
  setAvatarFailed(false);
1283
2010
  }, [avatarUrl]);
1284
2011
  const name = ((_a = reporter == null ? void 0 : reporter.name) == null ? void 0 : _a.trim()) || "";
@@ -1287,13 +2014,13 @@ function ReporterChip({
1287
2014
  const label = isAnonymous ? "Anonymous" : name;
1288
2015
  const title = isAnonymous ? "No reporter identity was passed to Glitchgrab \u2014 this report won't be attributed to anyone" : [name, reporter == null ? void 0 : reporter.email, reporter == null ? void 0 : reporter.role].filter(Boolean).join(" \xB7 ");
1289
2016
  const showAvatarImage = !!avatarUrl && !avatarFailed;
1290
- return /* @__PURE__ */ jsxs2(
2017
+ return /* @__PURE__ */ jsxs3(
1291
2018
  "span",
1292
2019
  {
1293
2020
  title,
1294
2021
  style: { display: "flex", alignItems: "center", gap: "6px", minWidth: 0 },
1295
2022
  children: [
1296
- /* @__PURE__ */ jsx2(
2023
+ /* @__PURE__ */ jsx3(
1297
2024
  "span",
1298
2025
  {
1299
2026
  "aria-hidden": "true",
@@ -1309,11 +2036,11 @@ function ReporterChip({
1309
2036
  fontSize: "8px",
1310
2037
  fontWeight: 700,
1311
2038
  letterSpacing: "0.02em",
1312
- background: isAnonymous ? t.inputBg : t.accent,
1313
- color: isAnonymous ? t.textMuted : t.accentText,
1314
- border: `1px solid ${isAnonymous ? t.inputBorder : "transparent"}`
2039
+ background: isAnonymous ? t2.inputBg : t2.accent,
2040
+ color: isAnonymous ? t2.textMuted : t2.accentText,
2041
+ border: `1px solid ${isAnonymous ? t2.inputBorder : "transparent"}`
1315
2042
  },
1316
- children: showAvatarImage ? /* @__PURE__ */ jsx2(
2043
+ children: showAvatarImage ? /* @__PURE__ */ jsx3(
1317
2044
  "img",
1318
2045
  {
1319
2046
  src: avatarUrl,
@@ -1323,9 +2050,9 @@ function ReporterChip({
1323
2050
  onError: () => setAvatarFailed(true),
1324
2051
  style: { width: "100%", height: "100%", objectFit: "cover" }
1325
2052
  }
1326
- ) : initials ? initials : /* @__PURE__ */ jsxs2("svg", { width: "10", height: "10", viewBox: "0 0 16 16", fill: "none", children: [
1327
- /* @__PURE__ */ jsx2("circle", { cx: "8", cy: "5.5", r: "2.75", stroke: "currentColor", strokeWidth: "1.4" }),
1328
- /* @__PURE__ */ jsx2(
2053
+ ) : initials ? initials : /* @__PURE__ */ jsxs3("svg", { width: "10", height: "10", viewBox: "0 0 16 16", fill: "none", children: [
2054
+ /* @__PURE__ */ jsx3("circle", { cx: "8", cy: "5.5", r: "2.75", stroke: "currentColor", strokeWidth: "1.4" }),
2055
+ /* @__PURE__ */ jsx3(
1329
2056
  "path",
1330
2057
  {
1331
2058
  d: "M2.75 13.5c0-2.35 2.35-3.75 5.25-3.75s5.25 1.4 5.25 3.75",
@@ -1337,12 +2064,12 @@ function ReporterChip({
1337
2064
  ] })
1338
2065
  }
1339
2066
  ),
1340
- /* @__PURE__ */ jsxs2(
2067
+ /* @__PURE__ */ jsxs3(
1341
2068
  "span",
1342
2069
  {
1343
2070
  style: {
1344
2071
  fontSize: "11px",
1345
- color: t.textMuted,
2072
+ color: t2.textMuted,
1346
2073
  overflow: "hidden",
1347
2074
  textOverflow: "ellipsis",
1348
2075
  whiteSpace: "nowrap"
@@ -1451,6 +2178,8 @@ function ReportDialog({
1451
2178
  report,
1452
2179
  sendFeedback: sendFeedback2,
1453
2180
  enhanceText: enhanceText2,
2181
+ assist,
2182
+ assistContext = null,
1454
2183
  transcribeAudio: transcribeAudio2,
1455
2184
  types,
1456
2185
  showSeverity = true,
@@ -1459,33 +2188,37 @@ function ReportDialog({
1459
2188
  onClose,
1460
2189
  headerSlot
1461
2190
  }) {
1462
- const [isEnhancing, setIsEnhancing] = useState2(false);
1463
- const [isEnhanced, setIsEnhanced] = useState2(false);
1464
- const [originalDescription, setOriginalDescription] = useState2(
2191
+ var _a, _b;
2192
+ const [isEnhancing, setIsEnhancing] = useState3(false);
2193
+ const [assistOpen, setAssistOpen] = useState3(false);
2194
+ const [assistNotice, setAssistNotice] = useState3(null);
2195
+ const [assistUsed, setAssistUsed] = useState3(false);
2196
+ const [isEnhanced, setIsEnhanced] = useState3(false);
2197
+ const [originalDescription, setOriginalDescription] = useState3(
1465
2198
  null
1466
2199
  );
1467
- const [isListening, setIsListening] = useState2(false);
1468
- const [isTranscribing, setIsTranscribing] = useState2(false);
1469
- const [voiceError, setVoiceError] = useState2(null);
1470
- const [screenshotDragOver, setScreenshotDragOver] = useState2(false);
1471
- const [mounted, setMounted] = useState2(false);
1472
- useEffect2(() => {
2200
+ const [isListening, setIsListening] = useState3(false);
2201
+ const [isTranscribing, setIsTranscribing] = useState3(false);
2202
+ const [voiceError, setVoiceError] = useState3(null);
2203
+ const [screenshotDragOver, setScreenshotDragOver] = useState3(false);
2204
+ const [mounted, setMounted] = useState3(false);
2205
+ useEffect3(() => {
1473
2206
  setMounted(true);
1474
2207
  }, []);
1475
- const [isOpen, setIsOpen] = useState2(false);
1476
- const [description, setDescription] = useState2("");
1477
- const [isSubmitting, setIsSubmitting] = useState2(false);
1478
- const [submitted, setSubmitted] = useState2(false);
1479
- const [screenshots, setScreenshots] = useState2([]);
1480
- const [attachments, setAttachments] = useState2([]);
1481
- const [previewIndex, setPreviewIndex] = useState2(null);
1482
- const [annotatingIndex, setAnnotatingIndex] = useState2(null);
1483
- const [previewZoomed, setPreviewZoomed] = useState2(false);
1484
- const [previewNatural, setPreviewNatural] = useState2(null);
1485
- const previewScrollRef = useRef2(null);
1486
- const previewImgElRef = useRef2(null);
1487
- const panRef = useRef2(null);
1488
- const zoomAnchorRef = useRef2(null);
2208
+ const [isOpen, setIsOpen] = useState3(false);
2209
+ const [description, setDescription] = useState3("");
2210
+ const [isSubmitting, setIsSubmitting] = useState3(false);
2211
+ const [submitted, setSubmitted] = useState3(false);
2212
+ const [screenshots, setScreenshots] = useState3([]);
2213
+ const [attachments, setAttachments] = useState3([]);
2214
+ const [previewIndex, setPreviewIndex] = useState3(null);
2215
+ const [annotatingIndex, setAnnotatingIndex] = useState3(null);
2216
+ const [previewZoomed, setPreviewZoomed] = useState3(false);
2217
+ const [previewNatural, setPreviewNatural] = useState3(null);
2218
+ const previewScrollRef = useRef3(null);
2219
+ const previewImgElRef = useRef3(null);
2220
+ const panRef = useRef3(null);
2221
+ const zoomAnchorRef = useRef3(null);
1489
2222
  const resetPreviewZoom = () => {
1490
2223
  setPreviewZoomed(false);
1491
2224
  setPreviewNatural(null);
@@ -1499,20 +2232,20 @@ function ReportDialog({
1499
2232
  resetPreviewZoom();
1500
2233
  setPreviewIndex(null);
1501
2234
  };
1502
- const fileInputRef = useRef2(null);
1503
- const modalRef = useRef2(null);
1504
- const previewImgRef = useRef2(null);
1505
- const textareaRef = useRef2(null);
1506
- const recognitionRef = useRef2(null);
1507
- const voiceBaseRef = useRef2("");
1508
- const usingWebSpeechRef = useRef2(false);
1509
- const textBeforeVoiceRef = useRef2("");
1510
- const mediaRecorderRef = useRef2(null);
1511
- const streamRef = useRef2(null);
1512
- const sarvamChunksRef = useRef2([]);
1513
- const spaceTimerRef = useRef2(null);
1514
- const isPushToTalkRef = useRef2(false);
1515
- useEffect2(() => {
2235
+ const fileInputRef = useRef3(null);
2236
+ const modalRef = useRef3(null);
2237
+ const previewImgRef = useRef3(null);
2238
+ const textareaRef = useRef3(null);
2239
+ const recognitionRef = useRef3(null);
2240
+ const voiceBaseRef = useRef3("");
2241
+ const usingWebSpeechRef = useRef3(false);
2242
+ const textBeforeVoiceRef = useRef3("");
2243
+ const mediaRecorderRef = useRef3(null);
2244
+ const streamRef = useRef3(null);
2245
+ const sarvamChunksRef = useRef3([]);
2246
+ const spaceTimerRef = useRef3(null);
2247
+ const isPushToTalkRef = useRef3(false);
2248
+ useEffect3(() => {
1516
2249
  if (!isOpen) return;
1517
2250
  const HOST_LAYERS = '[role="dialog"],[role="alertdialog"],[role="menu"],[role="listbox"]';
1518
2251
  const inerted = /* @__PURE__ */ new Set();
@@ -1538,13 +2271,13 @@ function ReportDialog({
1538
2271
  inerted.forEach((el) => el.removeAttribute("inert"));
1539
2272
  };
1540
2273
  }, [isOpen]);
1541
- const [step, setStep] = useState2(1);
1542
- const [reportType, setReportType] = useState2("BUG");
1543
- const [severity, setSeverity] = useState2("medium");
1544
- const [validationError, setValidationError] = useState2(null);
1545
- const [placeholderIdx, setPlaceholderIdx] = useState2(0);
1546
- const [rating, setRating] = useState2(0);
1547
- const [hoveredStar, setHoveredStar] = useState2(0);
2274
+ const [step, setStep] = useState3(1);
2275
+ const [reportType, setReportType] = useState3("BUG");
2276
+ const [severity, setSeverity] = useState3("medium");
2277
+ const [validationError, setValidationError] = useState3(null);
2278
+ const [placeholderIdx, setPlaceholderIdx] = useState3(0);
2279
+ const [rating, setRating] = useState3(0);
2280
+ const [hoveredStar, setHoveredStar] = useState3(0);
1548
2281
  const isRating = reportType === "RATING";
1549
2282
  const submitDisabled = isSubmitting || (isRating ? rating < 1 : !description.trim());
1550
2283
  const availableTypes = types != null ? types : [
@@ -1555,8 +2288,8 @@ function ReportDialog({
1555
2288
  "SECURITY",
1556
2289
  "QUESTION"
1557
2290
  ];
1558
- const tileGridRef = useRef2(null);
1559
- useEffect2(() => {
2291
+ const tileGridRef = useRef3(null);
2292
+ useEffect3(() => {
1560
2293
  if (!isOpen || step !== 1) return;
1561
2294
  const onKey = (e) => {
1562
2295
  const el = e.target;
@@ -1585,11 +2318,11 @@ function ReportDialog({
1585
2318
  return () => window.removeEventListener("keydown", onKey);
1586
2319
  }, [isOpen, step, sendFeedback2, availableTypes.join(",")]);
1587
2320
  const handleTileGridKeyDown = (e) => {
1588
- var _a, _b, _c;
2321
+ var _a2, _b2, _c;
1589
2322
  const keys = ["ArrowRight", "ArrowLeft", "ArrowDown", "ArrowUp"];
1590
2323
  if (!keys.includes(e.key)) return;
1591
2324
  const tiles = Array.from(
1592
- (_b = (_a = tileGridRef.current) == null ? void 0 : _a.querySelectorAll("button[data-gg-type]")) != null ? _b : []
2325
+ (_b2 = (_a2 = tileGridRef.current) == null ? void 0 : _a2.querySelectorAll("button[data-gg-type]")) != null ? _b2 : []
1593
2326
  );
1594
2327
  if (tiles.length === 0) return;
1595
2328
  e.preventDefault();
@@ -1599,7 +2332,7 @@ function ReportDialog({
1599
2332
  (_c = tiles[next]) == null ? void 0 : _c.focus();
1600
2333
  };
1601
2334
  const isDark = useIsDark();
1602
- const t = getTheme(isDark);
2335
+ const t2 = getTheme(isDark);
1603
2336
  const canZoomPreview = previewNatural !== null && typeof window !== "undefined" && (previewNatural.w > window.innerWidth - 32 || previewNatural.h > window.innerHeight - 80);
1604
2337
  const handleFileUpload = (e) => {
1605
2338
  const files = e.target.files;
@@ -1637,7 +2370,7 @@ function ReportDialog({
1637
2370
  if (shot) setScreenshots([shot]);
1638
2371
  setIsOpen(true);
1639
2372
  };
1640
- useEffect2(() => {
2373
+ useEffect3(() => {
1641
2374
  const handler = (e) => {
1642
2375
  if (isOpen) return;
1643
2376
  const detail = e.detail;
@@ -1651,7 +2384,7 @@ function ReportDialog({
1651
2384
  window.addEventListener("glitchgrab:open-report", handler);
1652
2385
  return () => window.removeEventListener("glitchgrab:open-report", handler);
1653
2386
  }, [isOpen, handleOpen]);
1654
- useEffect2(() => {
2387
+ useEffect3(() => {
1655
2388
  if (!isOpen) return;
1656
2389
  const handleEsc = (e) => {
1657
2390
  if (e.key === "Escape") {
@@ -1664,29 +2397,29 @@ function ReportDialog({
1664
2397
  document.addEventListener("keydown", handleEsc);
1665
2398
  return () => document.removeEventListener("keydown", handleEsc);
1666
2399
  }, [isOpen, previewIndex, previewZoomed, annotatingIndex]);
1667
- useEffect2(() => {
2400
+ useEffect3(() => {
1668
2401
  if (previewIndex === null || annotatingIndex !== null) return;
1669
2402
  const handlePointerDown = (e) => {
1670
- var _a;
1671
- if (!((_a = previewImgRef.current) == null ? void 0 : _a.contains(e.target))) {
2403
+ var _a2;
2404
+ if (!((_a2 = previewImgRef.current) == null ? void 0 : _a2.contains(e.target))) {
1672
2405
  closePreview();
1673
2406
  }
1674
2407
  };
1675
2408
  document.addEventListener("pointerdown", handlePointerDown, true);
1676
2409
  return () => document.removeEventListener("pointerdown", handlePointerDown, true);
1677
2410
  }, [previewIndex, annotatingIndex]);
1678
- useEffect2(() => {
1679
- var _a;
2411
+ useEffect3(() => {
2412
+ var _a2;
1680
2413
  const el = previewScrollRef.current;
1681
2414
  if (!previewZoomed || !el) return;
1682
- const anchor = (_a = zoomAnchorRef.current) != null ? _a : { fx: 0.5, fy: 0.5 };
2415
+ const anchor = (_a2 = zoomAnchorRef.current) != null ? _a2 : { fx: 0.5, fy: 0.5 };
1683
2416
  el.scrollLeft = anchor.fx * el.scrollWidth - el.clientWidth / 2;
1684
2417
  el.scrollTop = anchor.fy * el.scrollHeight - el.clientHeight / 2;
1685
2418
  }, [previewZoomed]);
1686
2419
  const togglePreviewZoom = (e) => {
1687
- var _a;
2420
+ var _a2;
1688
2421
  e.stopPropagation();
1689
- if ((_a = panRef.current) == null ? void 0 : _a.moved) return;
2422
+ if ((_a2 = panRef.current) == null ? void 0 : _a2.moved) return;
1690
2423
  if (!previewZoomed && !canZoomPreview) return;
1691
2424
  const img = previewImgElRef.current;
1692
2425
  if (!previewZoomed && img) {
@@ -1721,9 +2454,9 @@ function ReportDialog({
1721
2454
  el.scrollTop = start.top - dy;
1722
2455
  };
1723
2456
  const handlePanEnd = (e) => {
1724
- var _a, _b;
2457
+ var _a2, _b2;
1725
2458
  const el = previewScrollRef.current;
1726
- const moved = (_b = (_a = panRef.current) == null ? void 0 : _a.moved) != null ? _b : false;
2459
+ const moved = (_b2 = (_a2 = panRef.current) == null ? void 0 : _a2.moved) != null ? _b2 : false;
1727
2460
  try {
1728
2461
  el == null ? void 0 : el.releasePointerCapture(e.pointerId);
1729
2462
  } catch (e2) {
@@ -1737,12 +2470,12 @@ function ReportDialog({
1737
2470
  panRef.current = null;
1738
2471
  }
1739
2472
  };
1740
- useEffect2(() => {
2473
+ useEffect3(() => {
1741
2474
  if (!isOpen) return;
1742
2475
  const handlePaste = (e) => {
1743
- var _a;
2476
+ var _a2;
1744
2477
  try {
1745
- const items = (_a = e.clipboardData) == null ? void 0 : _a.items;
2478
+ const items = (_a2 = e.clipboardData) == null ? void 0 : _a2.items;
1746
2479
  if (!items) return;
1747
2480
  const pasted = [];
1748
2481
  for (let i = 0; i < items.length; i++) {
@@ -1760,7 +2493,7 @@ function ReportDialog({
1760
2493
  window.addEventListener("paste", handlePaste);
1761
2494
  return () => window.removeEventListener("paste", handlePaste);
1762
2495
  }, [isOpen]);
1763
- useEffect2(() => {
2496
+ useEffect3(() => {
1764
2497
  if (!isOpen || !transcribeAudio2) return;
1765
2498
  const id = setInterval(() => {
1766
2499
  setPlaceholderIdx((i) => (i + 1) % 2);
@@ -1768,16 +2501,16 @@ function ReportDialog({
1768
2501
  return () => clearInterval(id);
1769
2502
  }, [isOpen, transcribeAudio2]);
1770
2503
  const stopVoice = () => {
1771
- var _a, _b;
2504
+ var _a2, _b2;
1772
2505
  usingWebSpeechRef.current = false;
1773
- (_a = recognitionRef.current) == null ? void 0 : _a.stop();
2506
+ (_a2 = recognitionRef.current) == null ? void 0 : _a2.stop();
1774
2507
  recognitionRef.current = null;
1775
2508
  sarvamChunksRef.current = [];
1776
2509
  const stream = streamRef.current;
1777
2510
  streamRef.current = null;
1778
- stream == null ? void 0 : stream.getTracks().forEach((t2) => t2.stop());
2511
+ stream == null ? void 0 : stream.getTracks().forEach((t22) => t22.stop());
1779
2512
  try {
1780
- (_b = mediaRecorderRef.current) == null ? void 0 : _b.stop();
2513
+ (_b2 = mediaRecorderRef.current) == null ? void 0 : _b2.stop();
1781
2514
  } catch (e) {
1782
2515
  }
1783
2516
  mediaRecorderRef.current = null;
@@ -1785,16 +2518,28 @@ function ReportDialog({
1785
2518
  setIsTranscribing(false);
1786
2519
  };
1787
2520
  const stopListeningAndTranscribe = () => {
1788
- var _a, _b;
2521
+ var _a2, _b2;
1789
2522
  usingWebSpeechRef.current = false;
1790
- (_a = recognitionRef.current) == null ? void 0 : _a.stop();
2523
+ (_a2 = recognitionRef.current) == null ? void 0 : _a2.stop();
1791
2524
  recognitionRef.current = null;
1792
2525
  setIsListening(false);
1793
2526
  try {
1794
- (_b = mediaRecorderRef.current) == null ? void 0 : _b.stop();
2527
+ (_b2 = mediaRecorderRef.current) == null ? void 0 : _b2.stop();
1795
2528
  } catch (e) {
1796
2529
  }
1797
2530
  };
2531
+ const sheetUp = !!assist && assistOpen && !isRating;
2532
+ useEffect3(() => {
2533
+ const el = modalRef.current;
2534
+ if (!el) return;
2535
+ if (sheetUp) {
2536
+ el.setAttribute("inert", "");
2537
+ el.setAttribute("aria-hidden", "true");
2538
+ } else {
2539
+ el.removeAttribute("inert");
2540
+ el.removeAttribute("aria-hidden");
2541
+ }
2542
+ }, [sheetUp, isOpen]);
1798
2543
  const handleClose = () => {
1799
2544
  stopVoice();
1800
2545
  setIsOpen(false);
@@ -1810,6 +2555,9 @@ function ReportDialog({
1810
2555
  setVoiceError(null);
1811
2556
  setIsEnhanced(false);
1812
2557
  setOriginalDescription(null);
2558
+ setAssistOpen(false);
2559
+ setAssistUsed(false);
2560
+ setAssistNotice(null);
1813
2561
  };
1814
2562
  const toggleVoice = async () => {
1815
2563
  if (isListening) {
@@ -1837,7 +2585,7 @@ function ReportDialog({
1837
2585
  if (e.data.size > 0) sarvamChunksRef.current.push(e.data);
1838
2586
  };
1839
2587
  rec.onstop = async () => {
1840
- stream.getTracks().forEach((t2) => t2.stop());
2588
+ stream.getTracks().forEach((t22) => t22.stop());
1841
2589
  if (streamRef.current === stream) streamRef.current = null;
1842
2590
  mediaRecorderRef.current = null;
1843
2591
  const chunks = sarvamChunksRef.current;
@@ -1912,7 +2660,7 @@ function ReportDialog({
1912
2660
  }
1913
2661
  };
1914
2662
  const handleSpaceDown = (e) => {
1915
- var _a;
2663
+ var _a2;
1916
2664
  if (e.code !== "Space") return;
1917
2665
  if (isListening || isPushToTalkRef.current) {
1918
2666
  e.preventDefault();
@@ -1920,7 +2668,7 @@ function ReportDialog({
1920
2668
  }
1921
2669
  if (e.repeat || !transcribeAudio2 || isTranscribing || spaceTimerRef.current)
1922
2670
  return;
1923
- const pos = (_a = e.currentTarget.selectionStart) != null ? _a : description.length;
2671
+ const pos = (_a2 = e.currentTarget.selectionStart) != null ? _a2 : description.length;
1924
2672
  spaceTimerRef.current = setTimeout(() => {
1925
2673
  spaceTimerRef.current = null;
1926
2674
  isPushToTalkRef.current = true;
@@ -2009,9 +2757,9 @@ function ReportDialog({
2009
2757
  }
2010
2758
  };
2011
2759
  if (!mounted) return null;
2012
- return /* @__PURE__ */ jsxs2(Fragment, { children: [
2013
- isOpen && createPortal(
2014
- /* @__PURE__ */ jsx2("style", { children: `
2760
+ return /* @__PURE__ */ jsxs3(Fragment2, { children: [
2761
+ isOpen && createPortal2(
2762
+ /* @__PURE__ */ jsx3("style", { children: `
2015
2763
  @keyframes gg-pulse{0%,100%{opacity:1}50%{opacity:0.35}}
2016
2764
  @keyframes gg-b1{0%,100%{height:3px}40%{height:13px}}
2017
2765
  @keyframes gg-b2{0%,100%{height:8px}50%{height:3px}}
@@ -2038,7 +2786,7 @@ function ReportDialog({
2038
2786
  button[data-gg-type]{transition:transform .15s ease,border-color .15s ease,box-shadow .15s ease,background-color .15s ease}
2039
2787
  button[data-gg-type]:hover{transform:translateY(-2px);box-shadow:0 6px 16px rgba(0,0,0,.18)}
2040
2788
  button[data-gg-type]:active{transform:translateY(0) scale(.985);box-shadow:none}
2041
- button[data-gg-type]:focus-visible{outline:2px solid ${t.accent};outline-offset:2px}
2789
+ button[data-gg-type]:focus-visible{outline:2px solid ${t2.accent};outline-offset:2px}
2042
2790
  @keyframes gg-star-pop{0%{transform:scale(.6);opacity:0}60%{transform:scale(1.12)}100%{transform:scale(1);opacity:1}}
2043
2791
  button[data-gg-star]{transition:transform .12s ease}
2044
2792
  button[data-gg-star]:hover{transform:scale(1.18)}
@@ -2047,8 +2795,8 @@ function ReportDialog({
2047
2795
  ` }),
2048
2796
  document.body
2049
2797
  ),
2050
- isOpen && createPortal(
2051
- /* @__PURE__ */ jsx2(
2798
+ isOpen && createPortal2(
2799
+ /* @__PURE__ */ jsx3(
2052
2800
  "div",
2053
2801
  {
2054
2802
  "data-glitchgrab-layer": "",
@@ -2057,7 +2805,10 @@ function ReportDialog({
2057
2805
  inset: 0,
2058
2806
  zIndex: 2147483647,
2059
2807
  pointerEvents: "auto",
2060
- display: "flex",
2808
+ // Hidden, not unmounted, while the AI sheet is in charge — the
2809
+ // dialog's state IS the report, and unmounting would drop the
2810
+ // screenshots, attachments and step the reporter is on.
2811
+ display: sheetUp ? "none" : "flex",
2061
2812
  alignItems: "center",
2062
2813
  justifyContent: "center",
2063
2814
  backgroundColor: "rgba(0,0,0,0.5)",
@@ -2068,7 +2819,7 @@ function ReportDialog({
2068
2819
  },
2069
2820
  onPointerDown: (e) => e.stopPropagation(),
2070
2821
  onFocus: (e) => e.stopPropagation(),
2071
- children: /* @__PURE__ */ jsxs2(
2822
+ children: /* @__PURE__ */ jsxs3(
2072
2823
  "div",
2073
2824
  {
2074
2825
  ref: modalRef,
@@ -2081,25 +2832,25 @@ function ReportDialog({
2081
2832
  maxHeight: "calc(100dvh - 32px)",
2082
2833
  display: "flex",
2083
2834
  flexDirection: "column",
2084
- backgroundColor: t.bg,
2835
+ backgroundColor: t2.bg,
2085
2836
  borderRadius: "12px",
2086
2837
  boxShadow: "0 20px 60px rgba(0, 0, 0, 0.2), 0 4px 16px rgba(0, 0, 0, 0.1)",
2087
2838
  fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
2088
2839
  overflow: "hidden",
2089
- color: t.text,
2840
+ color: t2.text,
2090
2841
  isolation: "isolate"
2091
2842
  },
2092
2843
  children: [
2093
- /* @__PURE__ */ jsxs2(
2844
+ /* @__PURE__ */ jsxs3(
2094
2845
  "div",
2095
2846
  {
2096
2847
  style: {
2097
2848
  flexShrink: 0,
2098
2849
  padding: "16px 16px 12px",
2099
- borderBottom: `1px solid ${t.border}`
2850
+ borderBottom: `1px solid ${t2.border}`
2100
2851
  },
2101
2852
  children: [
2102
- /* @__PURE__ */ jsxs2(
2853
+ /* @__PURE__ */ jsxs3(
2103
2854
  "div",
2104
2855
  {
2105
2856
  style: {
@@ -2108,7 +2859,7 @@ function ReportDialog({
2108
2859
  alignItems: "center"
2109
2860
  },
2110
2861
  children: [
2111
- /* @__PURE__ */ jsxs2(
2862
+ /* @__PURE__ */ jsxs3(
2112
2863
  "div",
2113
2864
  {
2114
2865
  style: {
@@ -2117,7 +2868,7 @@ function ReportDialog({
2117
2868
  gap: "8px"
2118
2869
  },
2119
2870
  children: [
2120
- step > 1 && /* @__PURE__ */ jsx2(
2871
+ step > 1 && /* @__PURE__ */ jsx3(
2121
2872
  "button",
2122
2873
  {
2123
2874
  type: "button",
@@ -2131,18 +2882,18 @@ function ReportDialog({
2131
2882
  alignItems: "center"
2132
2883
  },
2133
2884
  "aria-label": "Back",
2134
- children: /* @__PURE__ */ jsx2(
2885
+ children: /* @__PURE__ */ jsx3(
2135
2886
  "svg",
2136
2887
  {
2137
2888
  width: "16",
2138
2889
  height: "16",
2139
2890
  viewBox: "0 0 16 16",
2140
2891
  fill: "none",
2141
- children: /* @__PURE__ */ jsx2(
2892
+ children: /* @__PURE__ */ jsx3(
2142
2893
  "path",
2143
2894
  {
2144
2895
  d: "M10 3L5 8L10 13",
2145
- stroke: t.textMuted,
2896
+ stroke: t2.textMuted,
2146
2897
  strokeWidth: "2",
2147
2898
  strokeLinecap: "round",
2148
2899
  strokeLinejoin: "round"
@@ -2152,13 +2903,13 @@ function ReportDialog({
2152
2903
  )
2153
2904
  }
2154
2905
  ),
2155
- /* @__PURE__ */ jsx2(
2906
+ /* @__PURE__ */ jsx3(
2156
2907
  "span",
2157
2908
  {
2158
2909
  style: {
2159
2910
  fontSize: "15px",
2160
2911
  fontWeight: 600,
2161
- color: t.text
2912
+ color: t2.text
2162
2913
  },
2163
2914
  children: step === 1 ? "What's on your mind?" : "Tell us more"
2164
2915
  }
@@ -2166,7 +2917,7 @@ function ReportDialog({
2166
2917
  ]
2167
2918
  }
2168
2919
  ),
2169
- /* @__PURE__ */ jsxs2(
2920
+ /* @__PURE__ */ jsxs3(
2170
2921
  "div",
2171
2922
  {
2172
2923
  style: {
@@ -2175,7 +2926,7 @@ function ReportDialog({
2175
2926
  gap: "8px"
2176
2927
  },
2177
2928
  children: [
2178
- step === 1 && /* @__PURE__ */ jsx2(
2929
+ step === 1 && /* @__PURE__ */ jsx3(
2179
2930
  "span",
2180
2931
  {
2181
2932
  title: "Press this anywhere to open Glitchgrab",
@@ -2185,15 +2936,15 @@ function ReportDialog({
2185
2936
  lineHeight: 1,
2186
2937
  padding: "3px 6px",
2187
2938
  borderRadius: "4px",
2188
- border: `1px solid ${t.inputBorder}`,
2189
- background: t.inputBg,
2190
- color: t.textMuted,
2939
+ border: `1px solid ${t2.inputBorder}`,
2940
+ background: t2.inputBg,
2941
+ color: t2.textMuted,
2191
2942
  whiteSpace: "nowrap"
2192
2943
  },
2193
2944
  children: getShortcutLabel()
2194
2945
  }
2195
2946
  ),
2196
- /* @__PURE__ */ jsx2(
2947
+ /* @__PURE__ */ jsx3(
2197
2948
  "button",
2198
2949
  {
2199
2950
  type: "button",
@@ -2208,7 +2959,7 @@ function ReportDialog({
2208
2959
  justifyContent: "center"
2209
2960
  },
2210
2961
  "aria-label": "Close",
2211
- children: /* @__PURE__ */ jsx2(
2962
+ children: /* @__PURE__ */ jsx3(
2212
2963
  "svg",
2213
2964
  {
2214
2965
  width: "16",
@@ -2216,11 +2967,11 @@ function ReportDialog({
2216
2967
  viewBox: "0 0 16 16",
2217
2968
  fill: "none",
2218
2969
  style: { display: "block" },
2219
- children: /* @__PURE__ */ jsx2(
2970
+ children: /* @__PURE__ */ jsx3(
2220
2971
  "path",
2221
2972
  {
2222
2973
  d: "M4 4L12 12M12 4L4 12",
2223
- stroke: t.textMuted,
2974
+ stroke: t2.textMuted,
2224
2975
  strokeWidth: "2",
2225
2976
  strokeLinecap: "round"
2226
2977
  }
@@ -2235,7 +2986,7 @@ function ReportDialog({
2235
2986
  ]
2236
2987
  }
2237
2988
  ),
2238
- /* @__PURE__ */ jsx2(
2989
+ /* @__PURE__ */ jsx3(
2239
2990
  "div",
2240
2991
  {
2241
2992
  style: {
@@ -2245,30 +2996,30 @@ function ReportDialog({
2245
2996
  gap: "0",
2246
2997
  marginTop: "12px"
2247
2998
  },
2248
- children: [1, 2].map((s, i) => /* @__PURE__ */ jsxs2(
2999
+ children: [1, 2].map((s, i) => /* @__PURE__ */ jsxs3(
2249
3000
  "div",
2250
3001
  {
2251
3002
  style: { display: "flex", alignItems: "center" },
2252
3003
  children: [
2253
- /* @__PURE__ */ jsx2(
3004
+ /* @__PURE__ */ jsx3(
2254
3005
  "div",
2255
3006
  {
2256
3007
  style: {
2257
3008
  width: "8px",
2258
3009
  height: "8px",
2259
3010
  borderRadius: "50%",
2260
- backgroundColor: s <= step ? t.accent : t.inputBorder,
3011
+ backgroundColor: s <= step ? t2.accent : t2.inputBorder,
2261
3012
  transition: "background-color 0.2s ease"
2262
3013
  }
2263
3014
  }
2264
3015
  ),
2265
- i < 1 && /* @__PURE__ */ jsx2(
3016
+ i < 1 && /* @__PURE__ */ jsx3(
2266
3017
  "div",
2267
3018
  {
2268
3019
  style: {
2269
3020
  width: "40px",
2270
3021
  height: "2px",
2271
- backgroundColor: s < step ? t.accent : t.inputBorder,
3022
+ backgroundColor: s < step ? t2.accent : t2.inputBorder,
2272
3023
  transition: "background-color 0.2s ease"
2273
3024
  }
2274
3025
  }
@@ -2282,7 +3033,7 @@ function ReportDialog({
2282
3033
  ]
2283
3034
  }
2284
3035
  ),
2285
- /* @__PURE__ */ jsx2(
3036
+ /* @__PURE__ */ jsx3(
2286
3037
  "div",
2287
3038
  {
2288
3039
  style: {
@@ -2291,13 +3042,13 @@ function ReportDialog({
2291
3042
  flex: "1 1 auto",
2292
3043
  minHeight: 0
2293
3044
  },
2294
- children: submitted ? /* @__PURE__ */ jsxs2(
3045
+ children: submitted ? /* @__PURE__ */ jsxs3(
2295
3046
  "div",
2296
3047
  {
2297
3048
  style: {
2298
3049
  textAlign: "center",
2299
3050
  padding: "20px 0",
2300
- color: t.accent,
3051
+ color: t2.accent,
2301
3052
  fontSize: "14px",
2302
3053
  fontWeight: 500
2303
3054
  },
@@ -2306,9 +3057,9 @@ function ReportDialog({
2306
3057
  " sent. Thank you!"
2307
3058
  ]
2308
3059
  }
2309
- ) : /* @__PURE__ */ jsxs2(Fragment, { children: [
2310
- step === 1 && headerSlot ? /* @__PURE__ */ jsx2("div", { style: { marginBottom: "14px" }, children: headerSlot }) : null,
2311
- step === 1 && sendFeedback2 && /* @__PURE__ */ jsxs2(
3060
+ ) : /* @__PURE__ */ jsxs3(Fragment2, { children: [
3061
+ step === 1 && headerSlot ? /* @__PURE__ */ jsx3("div", { style: { marginBottom: "14px" }, children: headerSlot }) : null,
3062
+ step === 1 && sendFeedback2 && /* @__PURE__ */ jsxs3(
2312
3063
  "div",
2313
3064
  {
2314
3065
  style: {
@@ -2325,16 +3076,16 @@ function ReportDialog({
2325
3076
  },
2326
3077
  onMouseLeave: () => setHoveredStar(0),
2327
3078
  children: [
2328
- /* @__PURE__ */ jsx2(
3079
+ /* @__PURE__ */ jsx3(
2329
3080
  "span",
2330
3081
  {
2331
- style: { fontSize: "13px", fontWeight: 600, color: t.text },
3082
+ style: { fontSize: "13px", fontWeight: 600, color: t2.text },
2332
3083
  children: "How are we doing?"
2333
3084
  }
2334
3085
  ),
2335
- /* @__PURE__ */ jsx2("span", { style: { display: "flex", gap: "4px" }, children: [1, 2, 3, 4, 5].map((star) => {
3086
+ /* @__PURE__ */ jsx3("span", { style: { display: "flex", gap: "4px" }, children: [1, 2, 3, 4, 5].map((star) => {
2336
3087
  const filled = star <= (hoveredStar || rating);
2337
- return /* @__PURE__ */ jsx2(
3088
+ return /* @__PURE__ */ jsx3(
2338
3089
  "button",
2339
3090
  {
2340
3091
  type: "button",
@@ -2354,7 +3105,7 @@ function ReportDialog({
2354
3105
  cursor: "pointer",
2355
3106
  lineHeight: 0
2356
3107
  },
2357
- children: /* @__PURE__ */ jsx2("svg", { width: "26", height: "26", viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ jsx2(
3108
+ children: /* @__PURE__ */ jsx3("svg", { width: "26", height: "26", viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ jsx3(
2358
3109
  "path",
2359
3110
  {
2360
3111
  d: "M12 3l2.6 5.3 5.9.9-4.3 4.1 1 5.8L12 16.4 6.8 19.1l1-5.8L3.5 9.2l5.9-.9L12 3z",
@@ -2371,7 +3122,7 @@ function ReportDialog({
2371
3122
  ]
2372
3123
  }
2373
3124
  ),
2374
- step === 1 && sendFeedback2 && /* @__PURE__ */ jsxs2(
3125
+ step === 1 && sendFeedback2 && /* @__PURE__ */ jsxs3(
2375
3126
  "div",
2376
3127
  {
2377
3128
  style: {
@@ -2381,13 +3132,13 @@ function ReportDialog({
2381
3132
  marginBottom: "16px"
2382
3133
  },
2383
3134
  children: [
2384
- /* @__PURE__ */ jsx2("span", { style: { flex: 1, height: "1px", background: t.border } }),
2385
- /* @__PURE__ */ jsx2("span", { style: { fontSize: "11px", color: t.textMuted }, children: "or report something" }),
2386
- /* @__PURE__ */ jsx2("span", { style: { flex: 1, height: "1px", background: t.border } })
3135
+ /* @__PURE__ */ jsx3("span", { style: { flex: 1, height: "1px", background: t2.border } }),
3136
+ /* @__PURE__ */ jsx3("span", { style: { fontSize: "11px", color: t2.textMuted }, children: "or report something" }),
3137
+ /* @__PURE__ */ jsx3("span", { style: { flex: 1, height: "1px", background: t2.border } })
2387
3138
  ]
2388
3139
  }
2389
3140
  ),
2390
- step === 1 && screenshots.length > 0 && /* @__PURE__ */ jsxs2(
3141
+ step === 1 && screenshots.length > 0 && /* @__PURE__ */ jsxs3(
2391
3142
  "div",
2392
3143
  {
2393
3144
  style: {
@@ -2396,12 +3147,12 @@ function ReportDialog({
2396
3147
  gap: "10px",
2397
3148
  marginBottom: "14px",
2398
3149
  padding: "8px 10px",
2399
- border: `1px solid ${t.inputBorder}`,
3150
+ border: `1px solid ${t2.inputBorder}`,
2400
3151
  borderRadius: "8px",
2401
- background: t.inputBg
3152
+ background: t2.inputBg
2402
3153
  },
2403
3154
  children: [
2404
- /* @__PURE__ */ jsx2(
3155
+ /* @__PURE__ */ jsx3(
2405
3156
  "img",
2406
3157
  {
2407
3158
  src: screenshots[0],
@@ -2411,13 +3162,13 @@ function ReportDialog({
2411
3162
  height: "24px",
2412
3163
  objectFit: "cover",
2413
3164
  borderRadius: "4px",
2414
- border: `1px solid ${t.border}`,
3165
+ border: `1px solid ${t2.border}`,
2415
3166
  flexShrink: 0
2416
3167
  }
2417
3168
  }
2418
3169
  ),
2419
- /* @__PURE__ */ jsx2("span", { style: { fontSize: "11px", color: t.textMuted, flex: 1 }, children: "Screenshot attached" }),
2420
- /* @__PURE__ */ jsx2(
3170
+ /* @__PURE__ */ jsx3("span", { style: { fontSize: "11px", color: t2.textMuted, flex: 1 }, children: "Screenshot attached" }),
3171
+ /* @__PURE__ */ jsx3(
2421
3172
  "button",
2422
3173
  {
2423
3174
  type: "button",
@@ -2426,7 +3177,7 @@ function ReportDialog({
2426
3177
  style: {
2427
3178
  border: "none",
2428
3179
  background: "transparent",
2429
- color: t.textMuted,
3180
+ color: t2.textMuted,
2430
3181
  cursor: "pointer",
2431
3182
  fontSize: "15px",
2432
3183
  lineHeight: 1,
@@ -2438,7 +3189,7 @@ function ReportDialog({
2438
3189
  ]
2439
3190
  }
2440
3191
  ),
2441
- step === 1 && /* @__PURE__ */ jsx2(
3192
+ step === 1 && /* @__PURE__ */ jsx3(
2442
3193
  "div",
2443
3194
  {
2444
3195
  ref: tileGridRef,
@@ -2448,7 +3199,7 @@ function ReportDialog({
2448
3199
  gridTemplateColumns: "1fr 1fr 1fr",
2449
3200
  gap: "10px"
2450
3201
  },
2451
- children: availableTypes.map((type) => /* @__PURE__ */ jsxs2(
3202
+ children: availableTypes.map((type) => /* @__PURE__ */ jsxs3(
2452
3203
  "button",
2453
3204
  {
2454
3205
  type: "button",
@@ -2464,21 +3215,21 @@ function ReportDialog({
2464
3215
  gap: "9px",
2465
3216
  padding: "18px 10px",
2466
3217
  borderRadius: "8px",
2467
- border: `1px solid ${t.inputBorder}`,
2468
- background: t.inputBg,
3218
+ border: `1px solid ${t2.inputBorder}`,
3219
+ background: t2.inputBg,
2469
3220
  cursor: "pointer",
2470
- color: t.text,
3221
+ color: t2.text,
2471
3222
  fontFamily: "inherit"
2472
3223
  },
2473
3224
  onMouseEnter: (e) => {
2474
- e.currentTarget.style.borderColor = t.accent;
3225
+ e.currentTarget.style.borderColor = t2.accent;
2475
3226
  },
2476
3227
  onMouseLeave: (e) => {
2477
- e.currentTarget.style.borderColor = t.inputBorder;
3228
+ e.currentTarget.style.borderColor = t2.inputBorder;
2478
3229
  },
2479
3230
  children: [
2480
- getTypeIcon(type, t.accent, 22),
2481
- /* @__PURE__ */ jsx2(
3231
+ getTypeIcon(type, t2.accent, 22),
3232
+ /* @__PURE__ */ jsx3(
2482
3233
  "span",
2483
3234
  {
2484
3235
  style: {
@@ -2496,8 +3247,8 @@ function ReportDialog({
2496
3247
  ))
2497
3248
  }
2498
3249
  ),
2499
- step === 2 && /* @__PURE__ */ jsxs2(Fragment, { children: [
2500
- /* @__PURE__ */ jsxs2(
3250
+ step === 2 && /* @__PURE__ */ jsxs3(Fragment2, { children: [
3251
+ /* @__PURE__ */ jsxs3(
2501
3252
  "button",
2502
3253
  {
2503
3254
  type: "button",
@@ -2509,22 +3260,22 @@ function ReportDialog({
2509
3260
  marginBottom: "10px",
2510
3261
  padding: "4px 10px 4px 8px",
2511
3262
  borderRadius: "999px",
2512
- border: `1px solid ${isRating ? "rgba(245,158,11,0.4)" : t.inputBorder}`,
2513
- background: isRating ? "rgba(245,158,11,0.1)" : t.inputBg,
2514
- color: t.text,
3263
+ border: `1px solid ${isRating ? "rgba(245,158,11,0.4)" : t2.inputBorder}`,
3264
+ background: isRating ? "rgba(245,158,11,0.1)" : t2.inputBg,
3265
+ color: t2.text,
2515
3266
  fontSize: "11px",
2516
3267
  fontWeight: 600,
2517
3268
  fontFamily: "inherit",
2518
3269
  cursor: "pointer"
2519
3270
  },
2520
3271
  children: [
2521
- getTypeIcon(reportType, isRating ? "#f59e0b" : t.accent, 13),
3272
+ getTypeIcon(reportType, isRating ? "#f59e0b" : t2.accent, 13),
2522
3273
  getTypeLabel(reportType),
2523
- /* @__PURE__ */ jsx2("span", { style: { color: t.textMuted, fontWeight: 400 }, children: "\xB7 change" })
3274
+ /* @__PURE__ */ jsx3("span", { style: { color: t2.textMuted, fontWeight: 400 }, children: "\xB7 change" })
2524
3275
  ]
2525
3276
  }
2526
3277
  ),
2527
- isRating && /* @__PURE__ */ jsx2(
3278
+ isRating && /* @__PURE__ */ jsx3(
2528
3279
  "div",
2529
3280
  {
2530
3281
  style: {
@@ -2535,7 +3286,7 @@ function ReportDialog({
2535
3286
  onMouseLeave: () => setHoveredStar(0),
2536
3287
  children: [1, 2, 3, 4, 5].map((star) => {
2537
3288
  const filled = star <= (hoveredStar || rating);
2538
- return /* @__PURE__ */ jsx2(
3289
+ return /* @__PURE__ */ jsx3(
2539
3290
  "button",
2540
3291
  {
2541
3292
  type: "button",
@@ -2552,12 +3303,12 @@ function ReportDialog({
2552
3303
  cursor: "pointer",
2553
3304
  lineHeight: 0
2554
3305
  },
2555
- children: /* @__PURE__ */ jsx2("svg", { width: "30", height: "30", viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ jsx2(
3306
+ children: /* @__PURE__ */ jsx3("svg", { width: "30", height: "30", viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ jsx3(
2556
3307
  "path",
2557
3308
  {
2558
3309
  d: "M12 3l2.6 5.3 5.9.9-4.3 4.1 1 5.8L12 16.4 6.8 19.1l1-5.8L3.5 9.2l5.9-.9L12 3z",
2559
3310
  fill: filled ? "#f59e0b" : "transparent",
2560
- stroke: filled ? "#f59e0b" : t.inputBorder,
3311
+ stroke: filled ? "#f59e0b" : t2.inputBorder,
2561
3312
  strokeWidth: "1.5",
2562
3313
  strokeLinejoin: "round"
2563
3314
  }
@@ -2568,8 +3319,47 @@ function ReportDialog({
2568
3319
  })
2569
3320
  }
2570
3321
  ),
2571
- /* @__PURE__ */ jsxs2("div", { style: { position: "relative" }, children: [
2572
- /* @__PURE__ */ jsx2(
3322
+ assist && !isRating && !assistUsed && /* @__PURE__ */ jsxs3(
3323
+ "button",
3324
+ {
3325
+ type: "button",
3326
+ onClick: () => {
3327
+ setAssistNotice(null);
3328
+ setAssistOpen(true);
3329
+ },
3330
+ style: {
3331
+ display: "inline-flex",
3332
+ alignItems: "center",
3333
+ gap: "6px",
3334
+ marginBottom: "10px",
3335
+ // 8px vertical keeps the tap target at ~32px.
3336
+ padding: "8px 10px",
3337
+ borderRadius: "6px",
3338
+ border: `1px solid ${t2.accent}`,
3339
+ background: "transparent",
3340
+ color: t2.accent,
3341
+ fontSize: "12px",
3342
+ fontWeight: 600,
3343
+ fontFamily: "inherit",
3344
+ cursor: "pointer"
3345
+ },
3346
+ title: "Answer a question or two and the assistant writes the report for you",
3347
+ children: [
3348
+ /* @__PURE__ */ jsx3("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx3(
3349
+ "path",
3350
+ {
3351
+ d: "M12 3l1.5 4.5L18 9l-4.5 1.5L12 15l-1.5-4.5L6 9l4.5-1.5L12 3zM19 15l.75 2.25L22 18l-2.25.75L19 21l-.75-2.25L16 18l2.25-.75L19 15z",
3352
+ stroke: t2.accent,
3353
+ strokeWidth: "1.5",
3354
+ strokeLinejoin: "round"
3355
+ }
3356
+ ) }),
3357
+ "Describe it with AI"
3358
+ ]
3359
+ }
3360
+ ),
3361
+ /* @__PURE__ */ jsxs3("div", { style: { position: "relative" }, children: [
3362
+ /* @__PURE__ */ jsx3(
2573
3363
  "textarea",
2574
3364
  {
2575
3365
  ref: textareaRef,
@@ -2588,29 +3378,29 @@ function ReportDialog({
2588
3378
  minHeight: "100px",
2589
3379
  padding: enhanceText2 ? "28px 12px 36px" : transcribeAudio2 ? "10px 12px 36px" : "10px 12px",
2590
3380
  borderRadius: "8px",
2591
- border: `1px solid ${isTranscribing ? "#f59e0b" : isListening ? t.accent : t.inputBorder}`,
3381
+ border: `1px solid ${isTranscribing ? "#f59e0b" : isListening ? t2.accent : t2.inputBorder}`,
2592
3382
  fontSize: "14px",
2593
3383
  fontFamily: "inherit",
2594
3384
  resize: "none",
2595
3385
  outline: "none",
2596
3386
  boxSizing: "border-box",
2597
- color: t.text,
2598
- backgroundColor: t.inputBg,
3387
+ color: t2.text,
3388
+ backgroundColor: t2.inputBg,
2599
3389
  transition: "border-color 0.2s ease"
2600
3390
  },
2601
3391
  onKeyDown: handleSpaceDown,
2602
3392
  onKeyUp: handleSpaceUp,
2603
3393
  onFocus: (e) => {
2604
- e.target.style.borderColor = t.accent;
3394
+ e.target.style.borderColor = t2.accent;
2605
3395
  },
2606
3396
  onBlur: (e) => {
2607
3397
  if (!isListening && !isTranscribing)
2608
- e.target.style.borderColor = t.inputBorder;
3398
+ e.target.style.borderColor = t2.inputBorder;
2609
3399
  },
2610
3400
  autoFocus: true
2611
3401
  }
2612
3402
  ),
2613
- (isListening || isTranscribing) && /* @__PURE__ */ jsxs2(
3403
+ (isListening || isTranscribing) && /* @__PURE__ */ jsxs3(
2614
3404
  "span",
2615
3405
  {
2616
3406
  style: {
@@ -2628,7 +3418,7 @@ function ReportDialog({
2628
3418
  zIndex: 1
2629
3419
  },
2630
3420
  children: [
2631
- /* @__PURE__ */ jsx2(
3421
+ /* @__PURE__ */ jsx3(
2632
3422
  "span",
2633
3423
  {
2634
3424
  style: {
@@ -2643,7 +3433,7 @@ function ReportDialog({
2643
3433
  }
2644
3434
  ),
2645
3435
  isTranscribing ? "Transcribing\u2026" : "REC",
2646
- isListening && !isTranscribing && /* @__PURE__ */ jsx2(
3436
+ isListening && !isTranscribing && /* @__PURE__ */ jsx3(
2647
3437
  "span",
2648
3438
  {
2649
3439
  style: {
@@ -2670,7 +3460,7 @@ function ReportDialog({
2670
3460
  dur: "0.55s",
2671
3461
  delay: "0.15s"
2672
3462
  }
2673
- ].map((b, i) => /* @__PURE__ */ jsx2(
3463
+ ].map((b, i) => /* @__PURE__ */ jsx3(
2674
3464
  "span",
2675
3465
  {
2676
3466
  style: {
@@ -2690,18 +3480,18 @@ function ReportDialog({
2690
3480
  ]
2691
3481
  }
2692
3482
  ),
2693
- enhanceText2 && /* @__PURE__ */ jsxs2(
3483
+ enhanceText2 && /* @__PURE__ */ jsxs3(
2694
3484
  "button",
2695
3485
  {
2696
3486
  type: "button",
2697
3487
  onClick: async () => {
2698
- var _a;
3488
+ var _a2;
2699
3489
  if (!description.trim() || isEnhancing) return;
2700
3490
  setIsEnhancing(true);
2701
3491
  try {
2702
3492
  const polished = await enhanceText2(
2703
3493
  description,
2704
- (_a = screenshots[0]) != null ? _a : null
3494
+ (_a2 = screenshots[0]) != null ? _a2 : null
2705
3495
  );
2706
3496
  if (polished && polished !== description) {
2707
3497
  setOriginalDescription(description);
@@ -2722,20 +3512,20 @@ function ReportDialog({
2722
3512
  display: "inline-flex",
2723
3513
  alignItems: "center",
2724
3514
  gap: "4px",
2725
- background: t.inputBg,
3515
+ background: t2.inputBg,
2726
3516
  border: "none",
2727
3517
  padding: "2px 6px",
2728
3518
  borderRadius: "4px",
2729
3519
  fontFamily: "inherit",
2730
3520
  fontSize: "11px",
2731
- color: t.textMuted,
3521
+ color: t2.textMuted,
2732
3522
  cursor: !description.trim() || isEnhancing ? "default" : "pointer",
2733
3523
  opacity: !description.trim() ? 0.5 : 1,
2734
3524
  zIndex: 1
2735
3525
  },
2736
3526
  title: "Polish grammar \u2014 preserves your meaning",
2737
3527
  children: [
2738
- /* @__PURE__ */ jsx2(
3528
+ /* @__PURE__ */ jsx3(
2739
3529
  "svg",
2740
3530
  {
2741
3531
  width: "11",
@@ -2743,11 +3533,11 @@ function ReportDialog({
2743
3533
  viewBox: "0 0 24 24",
2744
3534
  fill: "none",
2745
3535
  "aria-hidden": "true",
2746
- children: /* @__PURE__ */ jsx2(
3536
+ children: /* @__PURE__ */ jsx3(
2747
3537
  "path",
2748
3538
  {
2749
3539
  d: "M12 3l1.5 4.5L18 9l-4.5 1.5L12 15l-1.5-4.5L6 9l4.5-1.5L12 3zM19 15l.75 2.25L22 18l-2.25.75L19 21l-.75-2.25L16 18l2.25-.75L19 15z",
2750
- stroke: t.textMuted,
3540
+ stroke: t2.textMuted,
2751
3541
  strokeWidth: "1.5",
2752
3542
  strokeLinejoin: "round"
2753
3543
  }
@@ -2758,7 +3548,7 @@ function ReportDialog({
2758
3548
  ]
2759
3549
  }
2760
3550
  ),
2761
- transcribeAudio2 && /* @__PURE__ */ jsx2(
3551
+ transcribeAudio2 && /* @__PURE__ */ jsx3(
2762
3552
  "button",
2763
3553
  {
2764
3554
  type: "button",
@@ -2776,15 +3566,15 @@ function ReportDialog({
2776
3566
  alignItems: "center",
2777
3567
  justifyContent: "center",
2778
3568
  background: "transparent",
2779
- border: `1.5px solid ${isListening ? "#ef4444" : t.inputBorder}`,
3569
+ border: `1.5px solid ${isListening ? "#ef4444" : t2.inputBorder}`,
2780
3570
  borderRadius: "6px",
2781
- color: isListening ? "#ef4444" : t.textMuted,
3571
+ color: isListening ? "#ef4444" : t2.textMuted,
2782
3572
  cursor: "pointer",
2783
3573
  zIndex: 1,
2784
3574
  padding: 0,
2785
3575
  transition: "border-color 0.2s ease, color 0.2s ease"
2786
3576
  },
2787
- children: isListening ? /* @__PURE__ */ jsx2(
3577
+ children: isListening ? /* @__PURE__ */ jsx3(
2788
3578
  "svg",
2789
3579
  {
2790
3580
  width: "12",
@@ -2792,7 +3582,7 @@ function ReportDialog({
2792
3582
  viewBox: "0 0 24 24",
2793
3583
  fill: "currentColor",
2794
3584
  "aria-hidden": "true",
2795
- children: /* @__PURE__ */ jsx2(
3585
+ children: /* @__PURE__ */ jsx3(
2796
3586
  "rect",
2797
3587
  {
2798
3588
  x: "6",
@@ -2803,7 +3593,7 @@ function ReportDialog({
2803
3593
  }
2804
3594
  )
2805
3595
  }
2806
- ) : /* @__PURE__ */ jsxs2(
3596
+ ) : /* @__PURE__ */ jsxs3(
2807
3597
  "svg",
2808
3598
  {
2809
3599
  width: "13",
@@ -2812,7 +3602,7 @@ function ReportDialog({
2812
3602
  fill: "none",
2813
3603
  "aria-hidden": "true",
2814
3604
  children: [
2815
- /* @__PURE__ */ jsx2(
3605
+ /* @__PURE__ */ jsx3(
2816
3606
  "rect",
2817
3607
  {
2818
3608
  x: "9",
@@ -2824,7 +3614,7 @@ function ReportDialog({
2824
3614
  strokeWidth: "1.8"
2825
3615
  }
2826
3616
  ),
2827
- /* @__PURE__ */ jsx2(
3617
+ /* @__PURE__ */ jsx3(
2828
3618
  "path",
2829
3619
  {
2830
3620
  d: "M5 10a7 7 0 0014 0M12 19v3M9 22h6",
@@ -2839,7 +3629,7 @@ function ReportDialog({
2839
3629
  }
2840
3630
  )
2841
3631
  ] }),
2842
- transcribeAudio2 && !isListening && !isTranscribing && /* @__PURE__ */ jsxs2(
3632
+ transcribeAudio2 && !isListening && !isTranscribing && /* @__PURE__ */ jsxs3(
2843
3633
  "div",
2844
3634
  {
2845
3635
  style: {
@@ -2848,21 +3638,21 @@ function ReportDialog({
2848
3638
  gap: "5px",
2849
3639
  marginTop: "5px",
2850
3640
  fontSize: "11px",
2851
- color: t.text,
3641
+ color: t2.text,
2852
3642
  opacity: 0.55,
2853
3643
  userSelect: "none"
2854
3644
  },
2855
3645
  children: [
2856
- /* @__PURE__ */ jsxs2("svg", { width: "11", height: "11", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2857
- /* @__PURE__ */ jsx2("path", { d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z" }),
2858
- /* @__PURE__ */ jsx2("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
2859
- /* @__PURE__ */ jsx2("line", { x1: "12", x2: "12", y1: "19", y2: "22" })
3646
+ /* @__PURE__ */ jsxs3("svg", { width: "11", height: "11", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
3647
+ /* @__PURE__ */ jsx3("path", { d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z" }),
3648
+ /* @__PURE__ */ jsx3("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
3649
+ /* @__PURE__ */ jsx3("line", { x1: "12", x2: "12", y1: "19", y2: "22" })
2860
3650
  ] }),
2861
3651
  "Hold Space to speak \u2014 we'll transcribe it"
2862
3652
  ]
2863
3653
  }
2864
3654
  ),
2865
- isEnhanced && originalDescription !== null && /* @__PURE__ */ jsxs2(
3655
+ isEnhanced && originalDescription !== null && /* @__PURE__ */ jsxs3(
2866
3656
  "div",
2867
3657
  {
2868
3658
  style: {
@@ -2873,10 +3663,10 @@ function ReportDialog({
2873
3663
  padding: "6px 8px",
2874
3664
  borderRadius: "6px",
2875
3665
  background: isDark ? "rgba(34,211,238,0.06)" : "rgba(8,145,178,0.05)",
2876
- border: `1px solid ${t.accent}40`
3666
+ border: `1px solid ${t2.accent}40`
2877
3667
  },
2878
3668
  children: [
2879
- /* @__PURE__ */ jsx2(
3669
+ /* @__PURE__ */ jsx3(
2880
3670
  "svg",
2881
3671
  {
2882
3672
  width: "12",
@@ -2884,29 +3674,29 @@ function ReportDialog({
2884
3674
  viewBox: "0 0 24 24",
2885
3675
  fill: "none",
2886
3676
  style: { flexShrink: 0 },
2887
- children: /* @__PURE__ */ jsx2(
3677
+ children: /* @__PURE__ */ jsx3(
2888
3678
  "path",
2889
3679
  {
2890
3680
  d: "M12 3l1.5 4.5L18 9l-4.5 1.5L12 15l-1.5-4.5L6 9l4.5-1.5L12 3z",
2891
- stroke: t.accent,
3681
+ stroke: t2.accent,
2892
3682
  strokeWidth: "1.5",
2893
3683
  strokeLinejoin: "round"
2894
3684
  }
2895
3685
  )
2896
3686
  }
2897
3687
  ),
2898
- /* @__PURE__ */ jsx2(
3688
+ /* @__PURE__ */ jsx3(
2899
3689
  "span",
2900
3690
  {
2901
3691
  style: {
2902
3692
  fontSize: "11px",
2903
- color: t.textMuted,
3693
+ color: t2.textMuted,
2904
3694
  flex: 1
2905
3695
  },
2906
3696
  children: "AI enhanced"
2907
3697
  }
2908
3698
  ),
2909
- /* @__PURE__ */ jsx2(
3699
+ /* @__PURE__ */ jsx3(
2910
3700
  "button",
2911
3701
  {
2912
3702
  type: "button",
@@ -2917,9 +3707,9 @@ function ReportDialog({
2917
3707
  style: {
2918
3708
  padding: "2px 8px",
2919
3709
  borderRadius: "4px",
2920
- border: `1px solid ${t.accent}`,
2921
- background: t.accent,
2922
- color: t.accentText,
3710
+ border: `1px solid ${t2.accent}`,
3711
+ background: t2.accent,
3712
+ color: t2.accentText,
2923
3713
  fontSize: "11px",
2924
3714
  fontWeight: 600,
2925
3715
  cursor: "pointer",
@@ -2928,7 +3718,7 @@ function ReportDialog({
2928
3718
  children: "Keep"
2929
3719
  }
2930
3720
  ),
2931
- /* @__PURE__ */ jsx2(
3721
+ /* @__PURE__ */ jsx3(
2932
3722
  "button",
2933
3723
  {
2934
3724
  type: "button",
@@ -2940,9 +3730,9 @@ function ReportDialog({
2940
3730
  style: {
2941
3731
  padding: "2px 8px",
2942
3732
  borderRadius: "4px",
2943
- border: `1px solid ${t.inputBorder}`,
3733
+ border: `1px solid ${t2.inputBorder}`,
2944
3734
  background: "transparent",
2945
- color: t.textMuted,
3735
+ color: t2.textMuted,
2946
3736
  fontSize: "11px",
2947
3737
  fontWeight: 600,
2948
3738
  cursor: "pointer",
@@ -2954,7 +3744,7 @@ function ReportDialog({
2954
3744
  ]
2955
3745
  }
2956
3746
  ),
2957
- voiceError && /* @__PURE__ */ jsx2(
3747
+ voiceError && /* @__PURE__ */ jsx3(
2958
3748
  "p",
2959
3749
  {
2960
3750
  style: {
@@ -2966,13 +3756,26 @@ function ReportDialog({
2966
3756
  children: voiceError
2967
3757
  }
2968
3758
  ),
2969
- !isRating && /* @__PURE__ */ jsxs2("div", { style: { marginTop: "10px" }, children: [
2970
- /* @__PURE__ */ jsxs2(
3759
+ assistNotice && /* @__PURE__ */ jsx3(
3760
+ "p",
3761
+ {
3762
+ style: {
3763
+ color: t2.textMuted,
3764
+ fontSize: "12px",
3765
+ marginTop: "6px",
3766
+ marginBottom: 0,
3767
+ lineHeight: 1.5
3768
+ },
3769
+ children: assistNotice
3770
+ }
3771
+ ),
3772
+ !isRating && /* @__PURE__ */ jsxs3("div", { style: { marginTop: "10px" }, children: [
3773
+ /* @__PURE__ */ jsxs3(
2971
3774
  "span",
2972
3775
  {
2973
3776
  style: {
2974
3777
  fontSize: "12px",
2975
- color: t.textMuted,
3778
+ color: t2.textMuted,
2976
3779
  marginBottom: "6px",
2977
3780
  display: "block",
2978
3781
  fontWeight: 500
@@ -2983,7 +3786,7 @@ function ReportDialog({
2983
3786
  ]
2984
3787
  }
2985
3788
  ),
2986
- screenshots.length > 0 && /* @__PURE__ */ jsx2(
3789
+ screenshots.length > 0 && /* @__PURE__ */ jsx3(
2987
3790
  "div",
2988
3791
  {
2989
3792
  style: {
@@ -2992,7 +3795,7 @@ function ReportDialog({
2992
3795
  gap: "8px",
2993
3796
  marginBottom: "8px"
2994
3797
  },
2995
- children: screenshots.map((src, i) => /* @__PURE__ */ jsxs2(
3798
+ children: screenshots.map((src, i) => /* @__PURE__ */ jsxs3(
2996
3799
  "div",
2997
3800
  {
2998
3801
  style: {
@@ -3001,7 +3804,7 @@ function ReportDialog({
3001
3804
  height: "56px"
3002
3805
  },
3003
3806
  children: [
3004
- /* @__PURE__ */ jsx2(
3807
+ /* @__PURE__ */ jsx3(
3005
3808
  "img",
3006
3809
  {
3007
3810
  src,
@@ -3011,7 +3814,7 @@ function ReportDialog({
3011
3814
  width: "100%",
3012
3815
  height: "100%",
3013
3816
  borderRadius: "6px",
3014
- border: `1px solid ${t.border}`,
3817
+ border: `1px solid ${t2.border}`,
3015
3818
  objectFit: "cover",
3016
3819
  objectPosition: "top",
3017
3820
  cursor: "zoom-in",
@@ -3019,7 +3822,7 @@ function ReportDialog({
3019
3822
  }
3020
3823
  }
3021
3824
  ),
3022
- /* @__PURE__ */ jsx2(
3825
+ /* @__PURE__ */ jsx3(
3023
3826
  "button",
3024
3827
  {
3025
3828
  type: "button",
@@ -3045,14 +3848,14 @@ function ReportDialog({
3045
3848
  alignItems: "center",
3046
3849
  justifyContent: "center"
3047
3850
  },
3048
- children: /* @__PURE__ */ jsx2(
3851
+ children: /* @__PURE__ */ jsx3(
3049
3852
  "svg",
3050
3853
  {
3051
3854
  width: "8",
3052
3855
  height: "8",
3053
3856
  viewBox: "0 0 10 10",
3054
3857
  fill: "none",
3055
- children: /* @__PURE__ */ jsx2(
3858
+ children: /* @__PURE__ */ jsx3(
3056
3859
  "path",
3057
3860
  {
3058
3861
  d: "M1 1L9 9M9 1L1 9",
@@ -3065,7 +3868,7 @@ function ReportDialog({
3065
3868
  )
3066
3869
  }
3067
3870
  ),
3068
- /* @__PURE__ */ jsx2(
3871
+ /* @__PURE__ */ jsx3(
3069
3872
  "button",
3070
3873
  {
3071
3874
  type: "button",
@@ -3081,8 +3884,8 @@ function ReportDialog({
3081
3884
  height: "24px",
3082
3885
  borderRadius: "50%",
3083
3886
  border: "none",
3084
- background: t.accent,
3085
- color: t.accentText,
3887
+ background: t2.accent,
3888
+ color: t2.accentText,
3086
3889
  padding: 0,
3087
3890
  cursor: "pointer",
3088
3891
  display: "flex",
@@ -3090,14 +3893,14 @@ function ReportDialog({
3090
3893
  justifyContent: "center",
3091
3894
  boxShadow: "0 2px 8px rgba(0,0,0,0.45)"
3092
3895
  },
3093
- children: /* @__PURE__ */ jsx2(
3896
+ children: /* @__PURE__ */ jsx3(
3094
3897
  "svg",
3095
3898
  {
3096
3899
  width: "12",
3097
3900
  height: "12",
3098
3901
  viewBox: "0 0 24 24",
3099
3902
  fill: "none",
3100
- children: /* @__PURE__ */ jsx2(
3903
+ children: /* @__PURE__ */ jsx3(
3101
3904
  "path",
3102
3905
  {
3103
3906
  d: "M12 20h9M16.5 3.5a2.12 2.12 0 013 3L7 19l-4 1 1-4L16.5 3.5z",
@@ -3117,7 +3920,7 @@ function ReportDialog({
3117
3920
  ))
3118
3921
  }
3119
3922
  ),
3120
- attachments.length > 0 && /* @__PURE__ */ jsx2(
3923
+ attachments.length > 0 && /* @__PURE__ */ jsx3(
3121
3924
  "div",
3122
3925
  {
3123
3926
  style: {
@@ -3126,7 +3929,7 @@ function ReportDialog({
3126
3929
  gap: "6px",
3127
3930
  marginBottom: "8px"
3128
3931
  },
3129
- children: attachments.map((a, i) => /* @__PURE__ */ jsxs2(
3932
+ children: attachments.map((a, i) => /* @__PURE__ */ jsxs3(
3130
3933
  "div",
3131
3934
  {
3132
3935
  style: {
@@ -3135,10 +3938,10 @@ function ReportDialog({
3135
3938
  gap: "8px",
3136
3939
  padding: "6px 8px",
3137
3940
  borderRadius: "6px",
3138
- border: `1px solid ${t.border}`
3941
+ border: `1px solid ${t2.border}`
3139
3942
  },
3140
3943
  children: [
3141
- /* @__PURE__ */ jsxs2(
3944
+ /* @__PURE__ */ jsxs3(
3142
3945
  "svg",
3143
3946
  {
3144
3947
  width: "14",
@@ -3147,21 +3950,21 @@ function ReportDialog({
3147
3950
  fill: "none",
3148
3951
  style: { flexShrink: 0, opacity: 0.6 },
3149
3952
  children: [
3150
- /* @__PURE__ */ jsx2(
3953
+ /* @__PURE__ */ jsx3(
3151
3954
  "path",
3152
3955
  {
3153
3956
  d: "M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z",
3154
- stroke: t.textMuted,
3957
+ stroke: t2.textMuted,
3155
3958
  strokeWidth: "1.5",
3156
3959
  strokeLinecap: "round",
3157
3960
  strokeLinejoin: "round"
3158
3961
  }
3159
3962
  ),
3160
- /* @__PURE__ */ jsx2(
3963
+ /* @__PURE__ */ jsx3(
3161
3964
  "path",
3162
3965
  {
3163
3966
  d: "M14 2v6h6",
3164
- stroke: t.textMuted,
3967
+ stroke: t2.textMuted,
3165
3968
  strokeWidth: "1.5",
3166
3969
  strokeLinecap: "round",
3167
3970
  strokeLinejoin: "round"
@@ -3170,12 +3973,12 @@ function ReportDialog({
3170
3973
  ]
3171
3974
  }
3172
3975
  ),
3173
- /* @__PURE__ */ jsx2(
3976
+ /* @__PURE__ */ jsx3(
3174
3977
  "span",
3175
3978
  {
3176
3979
  style: {
3177
3980
  fontSize: "11px",
3178
- color: t.text,
3981
+ color: t2.text,
3179
3982
  flex: 1,
3180
3983
  overflow: "hidden",
3181
3984
  textOverflow: "ellipsis",
@@ -3184,17 +3987,17 @@ function ReportDialog({
3184
3987
  children: a.name
3185
3988
  }
3186
3989
  ),
3187
- /* @__PURE__ */ jsxs2(
3990
+ /* @__PURE__ */ jsxs3(
3188
3991
  "span",
3189
3992
  {
3190
- style: { fontSize: "10px", color: t.textMuted },
3993
+ style: { fontSize: "10px", color: t2.textMuted },
3191
3994
  children: [
3192
3995
  (a.size / 1024).toFixed(0),
3193
3996
  "KB"
3194
3997
  ]
3195
3998
  }
3196
3999
  ),
3197
- /* @__PURE__ */ jsx2(
4000
+ /* @__PURE__ */ jsx3(
3198
4001
  "button",
3199
4002
  {
3200
4003
  type: "button",
@@ -3218,14 +4021,14 @@ function ReportDialog({
3218
4021
  justifyContent: "center",
3219
4022
  flexShrink: 0
3220
4023
  },
3221
- children: /* @__PURE__ */ jsx2(
4024
+ children: /* @__PURE__ */ jsx3(
3222
4025
  "svg",
3223
4026
  {
3224
4027
  width: "8",
3225
4028
  height: "8",
3226
4029
  viewBox: "0 0 10 10",
3227
4030
  fill: "none",
3228
- children: /* @__PURE__ */ jsx2(
4031
+ children: /* @__PURE__ */ jsx3(
3229
4032
  "path",
3230
4033
  {
3231
4034
  d: "M1 1L9 9M9 1L1 9",
@@ -3244,12 +4047,12 @@ function ReportDialog({
3244
4047
  ))
3245
4048
  }
3246
4049
  ),
3247
- /* @__PURE__ */ jsx2(
4050
+ /* @__PURE__ */ jsx3(
3248
4051
  "div",
3249
4052
  {
3250
4053
  onClick: () => {
3251
- var _a;
3252
- return (_a = fileInputRef.current) == null ? void 0 : _a.click();
4054
+ var _a2;
4055
+ return (_a2 = fileInputRef.current) == null ? void 0 : _a2.click();
3253
4056
  },
3254
4057
  onDrop: (e) => {
3255
4058
  e.preventDefault();
@@ -3262,7 +4065,7 @@ function ReportDialog({
3262
4065
  },
3263
4066
  onDragLeave: () => setScreenshotDragOver(false),
3264
4067
  style: {
3265
- border: `1.5px dashed ${screenshotDragOver ? t.accent : t.inputBorder}`,
4068
+ border: `1.5px dashed ${screenshotDragOver ? t2.accent : t2.inputBorder}`,
3266
4069
  borderRadius: "8px",
3267
4070
  padding: screenshots.length + attachments.length > 0 ? "8px 12px" : "18px 12px",
3268
4071
  textAlign: "center",
@@ -3270,19 +4073,19 @@ function ReportDialog({
3270
4073
  background: screenshotDragOver ? isDark ? "rgba(34,211,238,0.06)" : "rgba(8,145,178,0.04)" : "transparent",
3271
4074
  transition: "border-color 0.15s ease, background 0.15s ease"
3272
4075
  },
3273
- children: screenshots.length + attachments.length > 0 ? /* @__PURE__ */ jsx2(
4076
+ children: screenshots.length + attachments.length > 0 ? /* @__PURE__ */ jsx3(
3274
4077
  "p",
3275
4078
  {
3276
4079
  style: {
3277
4080
  margin: 0,
3278
4081
  fontSize: "11px",
3279
4082
  fontWeight: 500,
3280
- color: t.textMuted
4083
+ color: t2.textMuted
3281
4084
  },
3282
4085
  children: screenshotDragOver ? "Drop to attach" : "+ Add more \xB7 Drag & drop \xB7 Paste"
3283
4086
  }
3284
- ) : /* @__PURE__ */ jsxs2(Fragment, { children: [
3285
- /* @__PURE__ */ jsxs2(
4087
+ ) : /* @__PURE__ */ jsxs3(Fragment2, { children: [
4088
+ /* @__PURE__ */ jsxs3(
3286
4089
  "svg",
3287
4090
  {
3288
4091
  width: "22",
@@ -3295,7 +4098,7 @@ function ReportDialog({
3295
4098
  opacity: 0.45
3296
4099
  },
3297
4100
  children: [
3298
- /* @__PURE__ */ jsx2(
4101
+ /* @__PURE__ */ jsx3(
3299
4102
  "rect",
3300
4103
  {
3301
4104
  x: "3",
@@ -3303,25 +4106,25 @@ function ReportDialog({
3303
4106
  width: "18",
3304
4107
  height: "18",
3305
4108
  rx: "2",
3306
- stroke: t.textMuted,
4109
+ stroke: t2.textMuted,
3307
4110
  strokeWidth: "1.5"
3308
4111
  }
3309
4112
  ),
3310
- /* @__PURE__ */ jsx2(
4113
+ /* @__PURE__ */ jsx3(
3311
4114
  "circle",
3312
4115
  {
3313
4116
  cx: "8.5",
3314
4117
  cy: "8.5",
3315
4118
  r: "1.5",
3316
- stroke: t.textMuted,
4119
+ stroke: t2.textMuted,
3317
4120
  strokeWidth: "1.5"
3318
4121
  }
3319
4122
  ),
3320
- /* @__PURE__ */ jsx2(
4123
+ /* @__PURE__ */ jsx3(
3321
4124
  "path",
3322
4125
  {
3323
4126
  d: "M21 15l-5-5L5 21",
3324
- stroke: t.textMuted,
4127
+ stroke: t2.textMuted,
3325
4128
  strokeWidth: "1.5",
3326
4129
  strokeLinecap: "round",
3327
4130
  strokeLinejoin: "round"
@@ -3330,25 +4133,25 @@ function ReportDialog({
3330
4133
  ]
3331
4134
  }
3332
4135
  ),
3333
- /* @__PURE__ */ jsx2(
4136
+ /* @__PURE__ */ jsx3(
3334
4137
  "p",
3335
4138
  {
3336
4139
  style: {
3337
4140
  margin: 0,
3338
4141
  fontSize: "12px",
3339
4142
  fontWeight: 600,
3340
- color: t.text
4143
+ color: t2.text
3341
4144
  },
3342
4145
  children: screenshotDragOver ? "Drop to attach" : "Add screenshots or files"
3343
4146
  }
3344
4147
  ),
3345
- /* @__PURE__ */ jsx2(
4148
+ /* @__PURE__ */ jsx3(
3346
4149
  "p",
3347
4150
  {
3348
4151
  style: {
3349
4152
  margin: "3px 0 0",
3350
4153
  fontSize: "11px",
3351
- color: t.textMuted
4154
+ color: t2.textMuted
3352
4155
  },
3353
4156
  children: "Images, PDF, DOC, XLS \xB7 Drag & drop \xB7 Paste \u2318V / Ctrl+V \xB7 Click to browse"
3354
4157
  }
@@ -3357,20 +4160,20 @@ function ReportDialog({
3357
4160
  }
3358
4161
  )
3359
4162
  ] }),
3360
- showSeverity && reportType === "BUG" && /* @__PURE__ */ jsxs2("div", { style: { marginTop: "10px" }, children: [
3361
- /* @__PURE__ */ jsx2(
4163
+ showSeverity && reportType === "BUG" && /* @__PURE__ */ jsxs3("div", { style: { marginTop: "10px" }, children: [
4164
+ /* @__PURE__ */ jsx3(
3362
4165
  "span",
3363
4166
  {
3364
4167
  style: {
3365
4168
  fontSize: "12px",
3366
- color: t.textMuted,
4169
+ color: t2.textMuted,
3367
4170
  marginBottom: "6px",
3368
4171
  display: "block"
3369
4172
  },
3370
4173
  children: "Severity"
3371
4174
  }
3372
4175
  ),
3373
- /* @__PURE__ */ jsx2("div", { style: { display: "flex", gap: "6px" }, children: ["low", "medium", "high"].map((s) => /* @__PURE__ */ jsx2(
4176
+ /* @__PURE__ */ jsx3("div", { style: { display: "flex", gap: "6px" }, children: ["low", "medium", "high"].map((s) => /* @__PURE__ */ jsx3(
3374
4177
  "button",
3375
4178
  {
3376
4179
  type: "button",
@@ -3379,9 +4182,9 @@ function ReportDialog({
3379
4182
  flex: 1,
3380
4183
  padding: "6px 0",
3381
4184
  borderRadius: "6px",
3382
- border: `1px solid ${severity === s ? t.accent : t.inputBorder}`,
3383
- background: severity === s ? t.accent : "transparent",
3384
- color: severity === s ? t.accentText : t.text,
4185
+ border: `1px solid ${severity === s ? t2.accent : t2.inputBorder}`,
4186
+ background: severity === s ? t2.accent : "transparent",
4187
+ color: severity === s ? t2.accentText : t2.text,
3385
4188
  fontSize: "12px",
3386
4189
  fontWeight: 600,
3387
4190
  cursor: "pointer",
@@ -3394,7 +4197,7 @@ function ReportDialog({
3394
4197
  s
3395
4198
  )) })
3396
4199
  ] }),
3397
- validationError && /* @__PURE__ */ jsx2(
4200
+ validationError && /* @__PURE__ */ jsx3(
3398
4201
  "p",
3399
4202
  {
3400
4203
  style: {
@@ -3405,7 +4208,7 @@ function ReportDialog({
3405
4208
  children: validationError
3406
4209
  }
3407
4210
  ),
3408
- /* @__PURE__ */ jsx2(
4211
+ /* @__PURE__ */ jsx3(
3409
4212
  "button",
3410
4213
  {
3411
4214
  type: "button",
@@ -3417,8 +4220,8 @@ function ReportDialog({
3417
4220
  padding: "10px",
3418
4221
  borderRadius: "8px",
3419
4222
  border: "none",
3420
- backgroundColor: submitDisabled ? t.bgSecondary : t.accent,
3421
- color: submitDisabled ? t.textMuted : t.accentText,
4223
+ backgroundColor: submitDisabled ? t2.bgSecondary : t2.accent,
4224
+ color: submitDisabled ? t2.textMuted : t2.accentText,
3422
4225
  fontSize: "14px",
3423
4226
  fontWeight: 600,
3424
4227
  cursor: submitDisabled ? "not-allowed" : "pointer",
@@ -3432,25 +4235,25 @@ function ReportDialog({
3432
4235
  ] })
3433
4236
  }
3434
4237
  ),
3435
- /* @__PURE__ */ jsxs2(
4238
+ /* @__PURE__ */ jsxs3(
3436
4239
  "div",
3437
4240
  {
3438
4241
  style: {
3439
4242
  padding: "8px 16px 10px",
3440
- borderTop: `1px solid ${t.border}`,
4243
+ borderTop: `1px solid ${t2.border}`,
3441
4244
  display: "flex",
3442
4245
  alignItems: "center",
3443
4246
  justifyContent: "space-between",
3444
4247
  gap: "12px"
3445
4248
  },
3446
4249
  children: [
3447
- /* @__PURE__ */ jsx2(ReporterChip, { reporter, t }),
3448
- /* @__PURE__ */ jsx2(
4250
+ /* @__PURE__ */ jsx3(ReporterChip, { reporter, t: t2 }),
4251
+ /* @__PURE__ */ jsx3(
3449
4252
  "span",
3450
4253
  {
3451
4254
  style: {
3452
4255
  fontSize: "11px",
3453
- color: t.textMuted,
4256
+ color: t2.textMuted,
3454
4257
  whiteSpace: "nowrap",
3455
4258
  flexShrink: 0
3456
4259
  },
@@ -3467,7 +4270,7 @@ function ReportDialog({
3467
4270
  ),
3468
4271
  document.body
3469
4272
  ),
3470
- /* @__PURE__ */ jsx2(
4273
+ /* @__PURE__ */ jsx3(
3471
4274
  "input",
3472
4275
  {
3473
4276
  ref: fileInputRef,
@@ -3478,8 +4281,8 @@ function ReportDialog({
3478
4281
  style: { display: "none" }
3479
4282
  }
3480
4283
  ),
3481
- isOpen && previewIndex !== null && screenshots[previewIndex] && createPortal(
3482
- /* @__PURE__ */ jsxs2(
4284
+ isOpen && previewIndex !== null && screenshots[previewIndex] && createPortal2(
4285
+ /* @__PURE__ */ jsxs3(
3483
4286
  "div",
3484
4287
  {
3485
4288
  "data-glitchgrab-layer": "",
@@ -3501,7 +4304,7 @@ function ReportDialog({
3501
4304
  },
3502
4305
  onMouseDown: (e) => e.stopPropagation(),
3503
4306
  children: [
3504
- /* @__PURE__ */ jsxs2(
4307
+ /* @__PURE__ */ jsxs3(
3505
4308
  "div",
3506
4309
  {
3507
4310
  ref: previewImgRef,
@@ -3513,7 +4316,7 @@ function ReportDialog({
3513
4316
  },
3514
4317
  onClick: (e) => e.stopPropagation(),
3515
4318
  children: [
3516
- /* @__PURE__ */ jsx2(
4319
+ /* @__PURE__ */ jsx3(
3517
4320
  "div",
3518
4321
  {
3519
4322
  ref: previewScrollRef,
@@ -3532,7 +4335,7 @@ function ReportDialog({
3532
4335
  touchAction: "none",
3533
4336
  cursor: "grab"
3534
4337
  } : { maxWidth: "100%", lineHeight: 0 },
3535
- children: /* @__PURE__ */ jsx2(
4338
+ children: /* @__PURE__ */ jsx3(
3536
4339
  "img",
3537
4340
  {
3538
4341
  ref: previewImgElRef,
@@ -3560,7 +4363,7 @@ function ReportDialog({
3560
4363
  )
3561
4364
  }
3562
4365
  ),
3563
- /* @__PURE__ */ jsxs2(
4366
+ /* @__PURE__ */ jsxs3(
3564
4367
  "button",
3565
4368
  {
3566
4369
  type: "button",
@@ -3578,8 +4381,8 @@ function ReportDialog({
3578
4381
  padding: "8px 14px",
3579
4382
  borderRadius: "999px",
3580
4383
  border: "none",
3581
- background: t.accent,
3582
- color: t.accentText,
4384
+ background: t2.accent,
4385
+ color: t2.accentText,
3583
4386
  fontSize: "13px",
3584
4387
  fontWeight: 700,
3585
4388
  cursor: "pointer",
@@ -3588,7 +4391,7 @@ function ReportDialog({
3588
4391
  animation: "gg-pulse 2s ease-in-out infinite"
3589
4392
  },
3590
4393
  children: [
3591
- /* @__PURE__ */ jsx2("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx2(
4394
+ /* @__PURE__ */ jsx3("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx3(
3592
4395
  "path",
3593
4396
  {
3594
4397
  d: "M12 20h9M16.5 3.5a2.12 2.12 0 013 3L7 19l-4 1 1-4L16.5 3.5z",
@@ -3605,7 +4408,7 @@ function ReportDialog({
3605
4408
  ]
3606
4409
  }
3607
4410
  ),
3608
- /* @__PURE__ */ jsx2(
4411
+ /* @__PURE__ */ jsx3(
3609
4412
  "div",
3610
4413
  {
3611
4414
  style: {
@@ -3614,11 +4417,11 @@ function ReportDialog({
3614
4417
  alignItems: "center",
3615
4418
  gap: "12px"
3616
4419
  },
3617
- children: /* @__PURE__ */ jsx2(
4420
+ children: /* @__PURE__ */ jsx3(
3618
4421
  "span",
3619
4422
  {
3620
4423
  style: {
3621
- color: t.textMuted,
4424
+ color: t2.textMuted,
3622
4425
  fontSize: "12px"
3623
4426
  },
3624
4427
  children: [
@@ -3635,8 +4438,8 @@ function ReportDialog({
3635
4438
  ),
3636
4439
  document.body
3637
4440
  ),
3638
- isOpen && annotatingIndex !== null && screenshots[annotatingIndex] && createPortal(
3639
- /* @__PURE__ */ jsx2(
4441
+ isOpen && annotatingIndex !== null && screenshots[annotatingIndex] && createPortal2(
4442
+ /* @__PURE__ */ jsx3(
3640
4443
  AnnotationCanvas,
3641
4444
  {
3642
4445
  imageSrc: screenshots[annotatingIndex],
@@ -3650,6 +4453,52 @@ function ReportDialog({
3650
4453
  }
3651
4454
  ),
3652
4455
  document.body
4456
+ ),
4457
+ isOpen && sheetUp && /* @__PURE__ */ jsx3(
4458
+ AssistSheet,
4459
+ {
4460
+ assist,
4461
+ theme: {
4462
+ bg: t2.bg,
4463
+ bgSecondary: t2.bgSecondary,
4464
+ border: t2.border,
4465
+ text: t2.text,
4466
+ textMuted: t2.textMuted,
4467
+ inputBg: t2.inputBg,
4468
+ inputBorder: t2.inputBorder,
4469
+ accent: t2.accent,
4470
+ accentText: t2.accentText
4471
+ },
4472
+ screenshot: (_a = screenshots[0]) != null ? _a : null,
4473
+ attachmentCount: screenshots.length + attachments.length,
4474
+ context: { ...assistContext != null ? assistContext : {}, reportType },
4475
+ reportTypeLabel: getTypeLabel(reportType),
4476
+ projectSlot: headerSlot,
4477
+ reporterName: (_b = reporter == null ? void 0 : reporter.name) != null ? _b : null,
4478
+ description,
4479
+ onDescriptionChange: (value) => {
4480
+ setDescription(value);
4481
+ if (validationError) setValidationError(null);
4482
+ },
4483
+ severity,
4484
+ onSeverityChange: setSeverity,
4485
+ showSeverity,
4486
+ isSubmitting,
4487
+ submitted,
4488
+ onSend: () => void handleSubmit(),
4489
+ onDegrade: (message) => {
4490
+ setAssistOpen(false);
4491
+ setAssistUsed(true);
4492
+ setAssistNotice(message);
4493
+ },
4494
+ onClose: () => {
4495
+ setAssistOpen(false);
4496
+ requestAnimationFrame(() => {
4497
+ var _a2;
4498
+ return (_a2 = textareaRef.current) == null ? void 0 : _a2.focus();
4499
+ });
4500
+ }
4501
+ }
3653
4502
  )
3654
4503
  ] });
3655
4504
  }
@@ -3703,7 +4552,7 @@ function getTypeIcon(type, color, size = 24) {
3703
4552
  };
3704
4553
  switch (type) {
3705
4554
  case "RATING":
3706
- return /* @__PURE__ */ jsx2("svg", { ...props, children: /* @__PURE__ */ jsx2(
4555
+ return /* @__PURE__ */ jsx3("svg", { ...props, children: /* @__PURE__ */ jsx3(
3707
4556
  "path",
3708
4557
  {
3709
4558
  d: "M12 3l2.6 5.3 5.9.9-4.3 4.1 1 5.8L12 16.4 6.8 19.1l1-5.8L3.5 9.2l5.9-.9L12 3z",
@@ -3713,7 +4562,7 @@ function getTypeIcon(type, color, size = 24) {
3713
4562
  }
3714
4563
  ) });
3715
4564
  case "BUG":
3716
- return /* @__PURE__ */ jsx2("svg", { ...props, children: /* @__PURE__ */ jsx2(
4565
+ return /* @__PURE__ */ jsx3("svg", { ...props, children: /* @__PURE__ */ jsx3(
3717
4566
  "path",
3718
4567
  {
3719
4568
  d: "M8 2L6.5 3.5M16 2L17.5 3.5M3 9H7M17 9H21M12 2a5 5 0 015 5v4a5 5 0 01-10 0V7a5 5 0 015-5zM7 16l-2 3M17 16l2 3",
@@ -3723,7 +4572,7 @@ function getTypeIcon(type, color, size = 24) {
3723
4572
  }
3724
4573
  ) });
3725
4574
  case "FEATURE_REQUEST":
3726
- return /* @__PURE__ */ jsx2("svg", { ...props, children: /* @__PURE__ */ jsx2(
4575
+ return /* @__PURE__ */ jsx3("svg", { ...props, children: /* @__PURE__ */ jsx3(
3727
4576
  "path",
3728
4577
  {
3729
4578
  d: "M12 2L15.09 8.26L22 9.27L17 14.14L18.18 21.02L12 17.77L5.82 21.02L7 14.14L2 9.27L8.91 8.26L12 2z",
@@ -3733,8 +4582,8 @@ function getTypeIcon(type, color, size = 24) {
3733
4582
  }
3734
4583
  ) });
3735
4584
  case "UI_IMPROVEMENT":
3736
- return /* @__PURE__ */ jsxs2("svg", { ...props, children: [
3737
- /* @__PURE__ */ jsx2(
4585
+ return /* @__PURE__ */ jsxs3("svg", { ...props, children: [
4586
+ /* @__PURE__ */ jsx3(
3738
4587
  "rect",
3739
4588
  {
3740
4589
  x: "3",
@@ -3746,7 +4595,7 @@ function getTypeIcon(type, color, size = 24) {
3746
4595
  strokeWidth: "1.5"
3747
4596
  }
3748
4597
  ),
3749
- /* @__PURE__ */ jsx2(
4598
+ /* @__PURE__ */ jsx3(
3750
4599
  "path",
3751
4600
  {
3752
4601
  d: "M3 9h18M9 21V9",
@@ -3757,7 +4606,7 @@ function getTypeIcon(type, color, size = 24) {
3757
4606
  )
3758
4607
  ] });
3759
4608
  case "PERFORMANCE":
3760
- return /* @__PURE__ */ jsx2("svg", { ...props, children: /* @__PURE__ */ jsx2(
4609
+ return /* @__PURE__ */ jsx3("svg", { ...props, children: /* @__PURE__ */ jsx3(
3761
4610
  "path",
3762
4611
  {
3763
4612
  d: "M12 21a9 9 0 100-18 9 9 0 000 18zM12 12l4-4M12 7v.01",
@@ -3768,7 +4617,7 @@ function getTypeIcon(type, color, size = 24) {
3768
4617
  }
3769
4618
  ) });
3770
4619
  case "SECURITY":
3771
- return /* @__PURE__ */ jsx2("svg", { ...props, children: /* @__PURE__ */ jsx2(
4620
+ return /* @__PURE__ */ jsx3("svg", { ...props, children: /* @__PURE__ */ jsx3(
3772
4621
  "path",
3773
4622
  {
3774
4623
  d: "M12 3l7 3v5c0 4.5-3 8.5-7 10-4-1.5-7-5.5-7-10V6l7-3z",
@@ -3778,9 +4627,9 @@ function getTypeIcon(type, color, size = 24) {
3778
4627
  }
3779
4628
  ) });
3780
4629
  case "QUESTION":
3781
- return /* @__PURE__ */ jsxs2("svg", { ...props, children: [
3782
- /* @__PURE__ */ jsx2("circle", { cx: "12", cy: "12", r: "10", stroke: color, strokeWidth: "1.5" }),
3783
- /* @__PURE__ */ jsx2(
4630
+ return /* @__PURE__ */ jsxs3("svg", { ...props, children: [
4631
+ /* @__PURE__ */ jsx3("circle", { cx: "12", cy: "12", r: "10", stroke: color, strokeWidth: "1.5" }),
4632
+ /* @__PURE__ */ jsx3(
3784
4633
  "path",
3785
4634
  {
3786
4635
  d: "M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3M12 17h.01",
@@ -3792,7 +4641,7 @@ function getTypeIcon(type, color, size = 24) {
3792
4641
  )
3793
4642
  ] });
3794
4643
  case "OTHER":
3795
- return /* @__PURE__ */ jsx2("svg", { ...props, children: /* @__PURE__ */ jsx2(
4644
+ return /* @__PURE__ */ jsx3("svg", { ...props, children: /* @__PURE__ */ jsx3(
3796
4645
  "path",
3797
4646
  {
3798
4647
  d: "M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2v10z",
@@ -3804,6 +4653,400 @@ function getTypeIcon(type, color, size = 24) {
3804
4653
  }
3805
4654
  }
3806
4655
 
4656
+ // src/booking-dialog.tsx
4657
+ import { useCallback, useEffect as useEffect4, useMemo, useState as useState4 } from "react";
4658
+ import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
4659
+ var t = {
4660
+ bg: "#141414",
4661
+ surface: "#1c1c1c",
4662
+ border: "#2a2a2a",
4663
+ text: "#e5e5e5",
4664
+ muted: "#9aa0a6",
4665
+ accent: "#3b82f6",
4666
+ danger: "#f87171"
4667
+ };
4668
+ function localZone() {
4669
+ try {
4670
+ return Intl.DateTimeFormat().resolvedOptions().timeZone;
4671
+ } catch (e) {
4672
+ return "UTC";
4673
+ }
4674
+ }
4675
+ function dayKey(iso) {
4676
+ return new Date(iso).toDateString();
4677
+ }
4678
+ function formatDay(iso) {
4679
+ return new Date(iso).toLocaleDateString(void 0, {
4680
+ weekday: "short",
4681
+ day: "numeric",
4682
+ month: "short"
4683
+ });
4684
+ }
4685
+ function formatTime(iso) {
4686
+ return new Date(iso).toLocaleTimeString(void 0, { hour: "2-digit", minute: "2-digit" });
4687
+ }
4688
+ function BookingDialog({
4689
+ token,
4690
+ baseUrl,
4691
+ open,
4692
+ onClose
4693
+ }) {
4694
+ var _a;
4695
+ const [step, setStep] = useState4("slots");
4696
+ const [slots, setSlots] = useState4(null);
4697
+ const [heading, setHeading] = useState4({
4698
+ title: "Book a demo",
4699
+ description: null
4700
+ });
4701
+ const [whatsappUrl, setWhatsappUrl] = useState4(null);
4702
+ const [selected, setSelected] = useState4(null);
4703
+ const [name, setName] = useState4("");
4704
+ const [email, setEmail] = useState4("");
4705
+ const [phone, setPhone] = useState4("");
4706
+ const [note, setNote] = useState4("");
4707
+ const [code, setCode] = useState4("");
4708
+ const [bookingId, setBookingId] = useState4(null);
4709
+ const [meetUrl, setMeetUrl] = useState4(null);
4710
+ const [busy, setBusy] = useState4(false);
4711
+ const [error, setError] = useState4(null);
4712
+ const headers = useMemo(
4713
+ () => ({ Authorization: `Bearer ${token}`, "Content-Type": "application/json" }),
4714
+ [token]
4715
+ );
4716
+ const loadSlots = useCallback(async () => {
4717
+ var _a2, _b, _c;
4718
+ setError(null);
4719
+ setSlots(null);
4720
+ try {
4721
+ const from = (/* @__PURE__ */ new Date()).toISOString();
4722
+ const to = new Date(Date.now() + 21 * 864e5).toISOString();
4723
+ const res = await fetch(
4724
+ `${baseUrl}/api/v1/sdk/booking/availability?from=${encodeURIComponent(from)}&to=${encodeURIComponent(to)}`,
4725
+ { headers }
4726
+ );
4727
+ const json = await res.json();
4728
+ if (!json.success) {
4729
+ setError((_a2 = json.error) != null ? _a2 : "Couldn't load available times");
4730
+ setSlots([]);
4731
+ return;
4732
+ }
4733
+ setSlots((_b = json.data.slots) != null ? _b : []);
4734
+ setHeading({ title: json.data.title, description: json.data.description });
4735
+ setWhatsappUrl((_c = json.data.whatsappUrl) != null ? _c : null);
4736
+ } catch (e) {
4737
+ setError("Couldn't reach the booking service");
4738
+ setSlots([]);
4739
+ }
4740
+ }, [baseUrl, headers]);
4741
+ useEffect4(() => {
4742
+ if (!open) return;
4743
+ setStep("slots");
4744
+ setSelected(null);
4745
+ setCode("");
4746
+ setBookingId(null);
4747
+ setError(null);
4748
+ void loadSlots();
4749
+ }, [open, loadSlots]);
4750
+ useEffect4(() => {
4751
+ if (!open) return;
4752
+ const onKey = (e) => {
4753
+ if (e.key === "Escape") onClose();
4754
+ };
4755
+ document.addEventListener("keydown", onKey, true);
4756
+ return () => document.removeEventListener("keydown", onKey, true);
4757
+ }, [open, onClose]);
4758
+ if (!open) return null;
4759
+ const byDay = /* @__PURE__ */ new Map();
4760
+ for (const slot of slots != null ? slots : []) {
4761
+ const key = dayKey(slot.startsAt);
4762
+ byDay.set(key, [...(_a = byDay.get(key)) != null ? _a : [], slot]);
4763
+ }
4764
+ async function startBooking() {
4765
+ var _a2;
4766
+ if (!selected) return;
4767
+ setBusy(true);
4768
+ setError(null);
4769
+ try {
4770
+ const res = await fetch(`${baseUrl}/api/v1/sdk/booking`, {
4771
+ method: "POST",
4772
+ headers,
4773
+ body: JSON.stringify({
4774
+ name,
4775
+ email,
4776
+ phone,
4777
+ note,
4778
+ startsAt: selected.startsAt,
4779
+ timezone: localZone()
4780
+ })
4781
+ });
4782
+ const json = await res.json();
4783
+ if (!json.success) {
4784
+ setError((_a2 = json.error) != null ? _a2 : "Couldn't hold that slot");
4785
+ return;
4786
+ }
4787
+ setBookingId(json.data.bookingId);
4788
+ setStep("code");
4789
+ } catch (e) {
4790
+ setError("Couldn't reach the booking service");
4791
+ } finally {
4792
+ setBusy(false);
4793
+ }
4794
+ }
4795
+ async function confirmBooking() {
4796
+ var _a2;
4797
+ if (!bookingId) return;
4798
+ setBusy(true);
4799
+ setError(null);
4800
+ try {
4801
+ const res = await fetch(`${baseUrl}/api/v1/sdk/booking/verify`, {
4802
+ method: "POST",
4803
+ headers,
4804
+ body: JSON.stringify({ bookingId, code })
4805
+ });
4806
+ const json = await res.json();
4807
+ if (!json.success) {
4808
+ setError((_a2 = json.error) != null ? _a2 : "Couldn't confirm that code");
4809
+ return;
4810
+ }
4811
+ setMeetUrl(json.data.meetUrl);
4812
+ setStep("done");
4813
+ } catch (e) {
4814
+ setError("Couldn't reach the booking service");
4815
+ } finally {
4816
+ setBusy(false);
4817
+ }
4818
+ }
4819
+ const canSubmitDetails = name.trim() && email.includes("@") && phone.replace(/\D/g, "").length >= 8;
4820
+ return /* @__PURE__ */ jsx4(
4821
+ "div",
4822
+ {
4823
+ onClick: (e) => {
4824
+ if (e.target === e.currentTarget) onClose();
4825
+ },
4826
+ style: {
4827
+ position: "fixed",
4828
+ inset: 0,
4829
+ zIndex: 2147483e3,
4830
+ background: "rgba(0,0,0,.6)",
4831
+ display: "flex",
4832
+ alignItems: "center",
4833
+ justifyContent: "center",
4834
+ padding: 16,
4835
+ fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif"
4836
+ },
4837
+ children: /* @__PURE__ */ jsxs4(
4838
+ "div",
4839
+ {
4840
+ role: "dialog",
4841
+ "aria-modal": "true",
4842
+ "aria-label": heading.title,
4843
+ style: {
4844
+ width: "min(440px, 100%)",
4845
+ maxHeight: "min(660px, 90vh)",
4846
+ display: "flex",
4847
+ flexDirection: "column",
4848
+ background: t.bg,
4849
+ color: t.text,
4850
+ borderRadius: 16,
4851
+ boxShadow: "0 20px 60px rgba(0,0,0,.55)",
4852
+ overflow: "hidden"
4853
+ },
4854
+ children: [
4855
+ /* @__PURE__ */ jsxs4(
4856
+ "div",
4857
+ {
4858
+ style: {
4859
+ padding: "16px 18px",
4860
+ borderBottom: `1px solid ${t.border}`,
4861
+ display: "flex",
4862
+ alignItems: "flex-start",
4863
+ justifyContent: "space-between",
4864
+ gap: 12
4865
+ },
4866
+ children: [
4867
+ /* @__PURE__ */ jsxs4("div", { children: [
4868
+ /* @__PURE__ */ jsx4("div", { style: { fontSize: 15, fontWeight: 600 }, children: heading.title }),
4869
+ heading.description && /* @__PURE__ */ jsx4("div", { style: { fontSize: 12, color: t.muted, marginTop: 2 }, children: heading.description })
4870
+ ] }),
4871
+ /* @__PURE__ */ jsx4(
4872
+ "button",
4873
+ {
4874
+ onClick: onClose,
4875
+ "aria-label": "Close",
4876
+ style: { border: 0, background: "transparent", color: t.muted, fontSize: 20, cursor: "pointer", lineHeight: 1 },
4877
+ children: "\xD7"
4878
+ }
4879
+ )
4880
+ ]
4881
+ }
4882
+ ),
4883
+ /* @__PURE__ */ jsxs4("div", { style: { padding: 18, overflowY: "auto", flex: "1 1 auto" }, children: [
4884
+ error && /* @__PURE__ */ jsx4("div", { style: { color: t.danger, fontSize: 12, marginBottom: 12, lineHeight: 1.5 }, children: error }),
4885
+ step === "slots" && /* @__PURE__ */ jsxs4(Fragment3, { children: [
4886
+ whatsappUrl && /* @__PURE__ */ jsxs4(
4887
+ "a",
4888
+ {
4889
+ href: whatsappUrl,
4890
+ target: "_blank",
4891
+ rel: "noreferrer",
4892
+ style: {
4893
+ display: "block",
4894
+ marginBottom: 16,
4895
+ padding: "10px 14px",
4896
+ borderRadius: 10,
4897
+ border: `1px solid ${t.border}`,
4898
+ background: t.surface,
4899
+ color: t.text,
4900
+ fontSize: 13,
4901
+ textDecoration: "none"
4902
+ },
4903
+ children: [
4904
+ "\u{1F4AC} Rather book on WhatsApp?",
4905
+ /* @__PURE__ */ jsx4("span", { style: { display: "block", fontSize: 11, color: t.muted, marginTop: 2 }, children: "We'll ask the same questions in chat." })
4906
+ ]
4907
+ }
4908
+ ),
4909
+ slots === null && /* @__PURE__ */ jsx4("div", { style: { color: t.muted, fontSize: 13 }, children: "Finding times\u2026" }),
4910
+ (slots == null ? void 0 : slots.length) === 0 && !error && /* @__PURE__ */ jsx4("div", { style: { color: t.muted, fontSize: 13 }, children: "No times available right now." }),
4911
+ [...byDay.entries()].map(([day, daySlots]) => /* @__PURE__ */ jsxs4("div", { style: { marginBottom: 18 }, children: [
4912
+ /* @__PURE__ */ jsx4("div", { style: { fontSize: 11, color: t.muted, marginBottom: 8, textTransform: "uppercase", letterSpacing: ".6px" }, children: formatDay(daySlots[0].startsAt) }),
4913
+ /* @__PURE__ */ jsx4("div", { style: { display: "flex", flexWrap: "wrap", gap: 8 }, children: daySlots.map((slot) => /* @__PURE__ */ jsx4(
4914
+ "button",
4915
+ {
4916
+ onClick: () => {
4917
+ setSelected(slot);
4918
+ setStep("details");
4919
+ },
4920
+ style: {
4921
+ padding: "8px 14px",
4922
+ borderRadius: 999,
4923
+ border: `1px solid ${t.border}`,
4924
+ background: t.surface,
4925
+ color: t.text,
4926
+ fontSize: 13,
4927
+ cursor: "pointer"
4928
+ },
4929
+ children: formatTime(slot.startsAt)
4930
+ },
4931
+ slot.startsAt
4932
+ )) })
4933
+ ] }, day))
4934
+ ] }),
4935
+ step === "details" && selected && /* @__PURE__ */ jsxs4("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: [
4936
+ /* @__PURE__ */ jsxs4("div", { style: { fontSize: 13, color: t.muted }, children: [
4937
+ formatDay(selected.startsAt),
4938
+ " \xB7 ",
4939
+ formatTime(selected.startsAt),
4940
+ " \xB7 ",
4941
+ /* @__PURE__ */ jsx4(
4942
+ "button",
4943
+ {
4944
+ onClick: () => setStep("slots"),
4945
+ style: { border: 0, background: "transparent", color: t.accent, cursor: "pointer", fontSize: 13, padding: 0 },
4946
+ children: "change"
4947
+ }
4948
+ )
4949
+ ] }),
4950
+ /* @__PURE__ */ jsx4(Field, { label: "Your name", value: name, onChange: setName }),
4951
+ /* @__PURE__ */ jsx4(Field, { label: "Email", value: email, onChange: setEmail, type: "email" }),
4952
+ /* @__PURE__ */ jsx4(
4953
+ Field,
4954
+ {
4955
+ label: "Mobile number",
4956
+ value: phone,
4957
+ onChange: setPhone,
4958
+ type: "tel",
4959
+ hint: "We send a code here to confirm, then a reminder before the call."
4960
+ }
4961
+ ),
4962
+ /* @__PURE__ */ jsx4(Field, { label: "Anything we should know? (optional)", value: note, onChange: setNote }),
4963
+ /* @__PURE__ */ jsx4(
4964
+ "button",
4965
+ {
4966
+ onClick: startBooking,
4967
+ disabled: !canSubmitDetails || busy,
4968
+ style: primaryStyle(!canSubmitDetails || busy),
4969
+ children: busy ? "Sending code\u2026" : "Send verification code"
4970
+ }
4971
+ )
4972
+ ] }),
4973
+ step === "code" && /* @__PURE__ */ jsxs4("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: [
4974
+ /* @__PURE__ */ jsx4("div", { style: { fontSize: 13, color: t.muted, lineHeight: 1.5 }, children: "We sent a 4-digit code to your phone. Your slot is held for 10 minutes." }),
4975
+ /* @__PURE__ */ jsx4(Field, { label: "Code", value: code, onChange: setCode }),
4976
+ /* @__PURE__ */ jsx4(
4977
+ "button",
4978
+ {
4979
+ onClick: confirmBooking,
4980
+ disabled: code.trim().length < 4 || busy,
4981
+ style: primaryStyle(code.trim().length < 4 || busy),
4982
+ children: busy ? "Confirming\u2026" : "Confirm booking"
4983
+ }
4984
+ )
4985
+ ] }),
4986
+ step === "done" && /* @__PURE__ */ jsxs4("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: [
4987
+ /* @__PURE__ */ jsx4("div", { style: { fontSize: 15, fontWeight: 600 }, children: "You're booked." }),
4988
+ /* @__PURE__ */ jsxs4("div", { style: { fontSize: 13, color: t.muted, lineHeight: 1.6 }, children: [
4989
+ selected && `${formatDay(selected.startsAt)} at ${formatTime(selected.startsAt)}. `,
4990
+ "A calendar invite is on its way to ",
4991
+ email,
4992
+ ", and we'll send a WhatsApp reminder before the call."
4993
+ ] }),
4994
+ meetUrl && /* @__PURE__ */ jsx4("a", { href: meetUrl, target: "_blank", rel: "noreferrer", style: { ...primaryStyle(false), textAlign: "center", textDecoration: "none" }, children: "Open the meeting link" })
4995
+ ] })
4996
+ ] })
4997
+ ]
4998
+ }
4999
+ )
5000
+ }
5001
+ );
5002
+ }
5003
+ function primaryStyle(disabled) {
5004
+ return {
5005
+ marginTop: 4,
5006
+ padding: "10px 16px",
5007
+ borderRadius: 999,
5008
+ border: 0,
5009
+ background: disabled ? "#2a2a2a" : t.accent,
5010
+ color: disabled ? "#6b7280" : "#fff",
5011
+ fontSize: 14,
5012
+ fontWeight: 500,
5013
+ cursor: disabled ? "default" : "pointer"
5014
+ };
5015
+ }
5016
+ function Field({
5017
+ label,
5018
+ value,
5019
+ onChange,
5020
+ type = "text",
5021
+ hint
5022
+ }) {
5023
+ return /* @__PURE__ */ jsxs4("label", { style: { display: "block", fontSize: 11, color: t.muted }, children: [
5024
+ label,
5025
+ /* @__PURE__ */ jsx4(
5026
+ "input",
5027
+ {
5028
+ type,
5029
+ value,
5030
+ onChange: (e) => onChange(e.target.value),
5031
+ style: {
5032
+ display: "block",
5033
+ width: "100%",
5034
+ boxSizing: "border-box",
5035
+ marginTop: 4,
5036
+ padding: "9px 12px",
5037
+ background: t.surface,
5038
+ color: t.text,
5039
+ border: `1px solid ${t.border}`,
5040
+ borderRadius: 8,
5041
+ fontSize: 13,
5042
+ outline: "none"
5043
+ }
5044
+ }
5045
+ ),
5046
+ hint && /* @__PURE__ */ jsx4("div", { style: { marginTop: 4, fontSize: 10, color: t.muted }, children: hint })
5047
+ ] });
5048
+ }
5049
+
3807
5050
  // src/rejection.ts
3808
5051
  var DETAILS_MAX_LENGTH = 1e3;
3809
5052
  var MESSAGE_MAX_LENGTH = 200;
@@ -3859,6 +5102,36 @@ function describeShape(reason) {
3859
5102
  return "";
3860
5103
  }
3861
5104
  }
5105
+ var EVENT_URL_MAX_LENGTH = 120;
5106
+ function isEventLike(reason) {
5107
+ try {
5108
+ if (typeof Event !== "undefined" && reason instanceof Event) return true;
5109
+ const source = reason;
5110
+ return typeof (source == null ? void 0 : source.type) === "string" && typeof (source == null ? void 0 : source.isTrusted) === "boolean";
5111
+ } catch (e) {
5112
+ return false;
5113
+ }
5114
+ }
5115
+ function describeEvent(reason) {
5116
+ var _a, _b, _c, _d, _e;
5117
+ const parts = [];
5118
+ try {
5119
+ const source = reason;
5120
+ const name = ((_a = source.constructor) == null ? void 0 : _a.name) || "Event";
5121
+ parts.push(`${name} ("${String((_b = source.type) != null ? _b : "")}")`);
5122
+ } catch (e) {
5123
+ parts.push("Event");
5124
+ }
5125
+ try {
5126
+ const target = reason.target;
5127
+ const tag = (_c = target == null ? void 0 : target.tagName) == null ? void 0 : _c.toLowerCase();
5128
+ if (tag) parts.push(`from <${tag}>`);
5129
+ const url = (_e = (_d = readString(target == null ? void 0 : target.currentSrc)) != null ? _d : readString(target == null ? void 0 : target.src)) != null ? _e : readString(target == null ? void 0 : target.href);
5130
+ if (url) parts.push(`\u2014 ${url.split(/[?#]/)[0].slice(0, EVENT_URL_MAX_LENGTH)}`);
5131
+ } catch (e) {
5132
+ }
5133
+ return parts.join(" ").slice(0, MESSAGE_MAX_LENGTH);
5134
+ }
3862
5135
  function describeRejection(reason) {
3863
5136
  var _a, _b, _c, _d, _e, _f, _g, _h;
3864
5137
  try {
@@ -3883,7 +5156,7 @@ function describeRejection(reason) {
3883
5156
  const message = (_h = (_g = (_f = (_e = (_d = (_c = (_b = readString(source.message)) != null ? _b : readString(nestedError)) != null ? _c : readString(nestedError == null ? void 0 : nestedError.message)) != null ? _d : readScalar(source.code)) != null ? _e : readString(source.name)) != null ? _f : readScalar(source.status)) != null ? _g : readString(source.statusText)) != null ? _h : "";
3884
5157
  const details = serialize(reason);
3885
5158
  return {
3886
- message: message || describeShape(reason),
5159
+ message: message || (isEventLike(reason) ? describeEvent(reason) : describeShape(reason)),
3887
5160
  stack,
3888
5161
  details
3889
5162
  };
@@ -3911,7 +5184,7 @@ function matchesShortcut(e) {
3911
5184
  }
3912
5185
 
3913
5186
  // src/provider.tsx
3914
- import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
5187
+ import { Fragment as Fragment4, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
3915
5188
  var DEFAULT_BASE_URL2 = "https://glitchgrab.dev";
3916
5189
  var GlitchgrabContext = createContext(null);
3917
5190
  function useGlitchgrab() {
@@ -3938,7 +5211,7 @@ function GlitchgrabProviderInner({
3938
5211
  context: appContext2,
3939
5212
  responseBodyOrigins: responseBodyOrigins2
3940
5213
  }) {
3941
- const visitedPagesRef = useRef3([]);
5214
+ const visitedPagesRef = useRef4([]);
3942
5215
  setRelease(release2);
3943
5216
  if (appContext2) setContexts(appContext2);
3944
5217
  registerCaptureConfig({
@@ -3950,12 +5223,12 @@ function GlitchgrabProviderInner({
3950
5223
  onError,
3951
5224
  onReportSent
3952
5225
  });
3953
- useEffect3(() => {
5226
+ useEffect5(() => {
3954
5227
  if (enableBreadcrumbs) {
3955
5228
  initBreadcrumbs(maxBreadcrumbs2, { responseBodyOrigins: responseBodyOrigins2 });
3956
5229
  }
3957
5230
  }, [enableBreadcrumbs, maxBreadcrumbs2, responseBodyOrigins2 == null ? void 0 : responseBodyOrigins2.join(",")]);
3958
- useEffect3(() => {
5231
+ useEffect5(() => {
3959
5232
  try {
3960
5233
  if (typeof window === "undefined") return;
3961
5234
  const trackPage = () => {
@@ -3992,7 +5265,7 @@ function GlitchgrabProviderInner({
3992
5265
  } catch (e) {
3993
5266
  }
3994
5267
  }, []);
3995
- useEffect3(() => {
5268
+ useEffect5(() => {
3996
5269
  try {
3997
5270
  if (typeof window === "undefined") return;
3998
5271
  if (process.env.NODE_ENV === "development") return;
@@ -4119,7 +5392,7 @@ function GlitchgrabProviderInner({
4119
5392
  } catch (e) {
4120
5393
  }
4121
5394
  }, [token, baseUrl, onError, onReportSent, session, ignoreErrors]);
4122
- const report = useCallback(
5395
+ const report = useCallback2(
4123
5396
  async (type, description, metadata) => {
4124
5397
  var _a;
4125
5398
  try {
@@ -4153,11 +5426,11 @@ function GlitchgrabProviderInner({
4153
5426
  },
4154
5427
  [token, baseUrl, onReportSent, session]
4155
5428
  );
4156
- const reportBug = useCallback(
5429
+ const reportBug = useCallback2(
4157
5430
  (description, metadata) => report("BUG", description, metadata),
4158
5431
  [report]
4159
5432
  );
4160
- const feedback = useCallback(
5433
+ const feedback = useCallback2(
4161
5434
  async (rating, message, metadata) => {
4162
5435
  try {
4163
5436
  const context = captureContext(visitedPagesRef.current);
@@ -4185,32 +5458,32 @@ function GlitchgrabProviderInner({
4185
5458
  },
4186
5459
  [token, baseUrl, session]
4187
5460
  );
4188
- const openFeedbackDialog = useCallback(() => {
5461
+ const openFeedbackDialog = useCallback2(() => {
4189
5462
  if (typeof window !== "undefined") {
4190
5463
  window.dispatchEvent(
4191
5464
  new CustomEvent("glitchgrab:open-report", { detail: { type: "RATING" } })
4192
5465
  );
4193
5466
  }
4194
5467
  }, []);
4195
- const captureError2 = useCallback(
5468
+ const captureError2 = useCallback2(
4196
5469
  (error, options) => {
4197
5470
  captureError(error, options);
4198
5471
  },
4199
5472
  []
4200
5473
  );
4201
- const setContext2 = useCallback((key, value) => {
5474
+ const setContext2 = useCallback2((key, value) => {
4202
5475
  setContext(key, value);
4203
5476
  }, []);
4204
- const setContexts2 = useCallback((values) => {
5477
+ const setContexts2 = useCallback2((values) => {
4205
5478
  setContexts(values);
4206
5479
  }, []);
4207
- const addBreadcrumb2 = useCallback(
5480
+ const addBreadcrumb2 = useCallback2(
4208
5481
  (message, data) => {
4209
5482
  addBreadcrumb("custom", message, data);
4210
5483
  },
4211
5484
  []
4212
5485
  );
4213
- const enhance = useCallback(
5486
+ const enhance = useCallback2(
4214
5487
  async (text, screenshot) => {
4215
5488
  try {
4216
5489
  const ctx = captureContext(visitedPagesRef.current);
@@ -4226,7 +5499,27 @@ function GlitchgrabProviderInner({
4226
5499
  },
4227
5500
  [token, baseUrl]
4228
5501
  );
4229
- const transcribe = useCallback(
5502
+ const assist = useCallback2(
5503
+ async (params) => {
5504
+ var _a;
5505
+ const ctx = captureContext(visitedPagesRef.current);
5506
+ return assistTurn(
5507
+ {
5508
+ ...params,
5509
+ context: {
5510
+ ...(_a = params.context) != null ? _a : {},
5511
+ url: ctx.url,
5512
+ visitedPages: ctx.visitedPages.slice(-5),
5513
+ breadcrumbs: ctx.breadcrumbs.slice(-25).map((b) => ({ type: b.type, message: b.message }))
5514
+ }
5515
+ },
5516
+ token,
5517
+ baseUrl
5518
+ );
5519
+ },
5520
+ [token, baseUrl]
5521
+ );
5522
+ const transcribe = useCallback2(
4230
5523
  async (blob) => {
4231
5524
  try {
4232
5525
  return await transcribeAudio(blob, token, baseUrl);
@@ -4236,12 +5529,12 @@ function GlitchgrabProviderInner({
4236
5529
  },
4237
5530
  [token, baseUrl]
4238
5531
  );
4239
- const openReportDialog = useCallback((options) => {
5532
+ const openReportDialog = useCallback2((options) => {
4240
5533
  if (typeof window !== "undefined") {
4241
5534
  window.dispatchEvent(new CustomEvent("glitchgrab:open-report", { detail: options }));
4242
5535
  }
4243
5536
  }, []);
4244
- useEffect3(() => {
5537
+ useEffect5(() => {
4245
5538
  try {
4246
5539
  if (typeof document === "undefined") return;
4247
5540
  document.documentElement.setAttribute("data-glitchgrab-sdk", "1");
@@ -4249,8 +5542,11 @@ function GlitchgrabProviderInner({
4249
5542
  } catch (e) {
4250
5543
  }
4251
5544
  }, []);
4252
- const [projectName, setProjectName] = useState3(null);
4253
- useEffect3(() => {
5545
+ const [projectName, setProjectName] = useState5(null);
5546
+ const [aiAssist, setAiAssist] = useState5(false);
5547
+ const [bookingOpen, setBookingOpen] = useState5(false);
5548
+ const openBookingDialog = useCallback2(() => setBookingOpen(true), []);
5549
+ useEffect5(() => {
4254
5550
  let cancelled = false;
4255
5551
  fetch(`${baseUrl}/api/v1/sdk/project`, {
4256
5552
  headers: { Authorization: `Bearer ${token}` }
@@ -4258,13 +5554,14 @@ function GlitchgrabProviderInner({
4258
5554
  var _a;
4259
5555
  if (cancelled || !(json == null ? void 0 : json.success) || !((_a = json.data) == null ? void 0 : _a.name)) return;
4260
5556
  setProjectName(json.data.name);
5557
+ setAiAssist(json.data.aiAssist === true);
4261
5558
  }).catch(() => {
4262
5559
  });
4263
5560
  return () => {
4264
5561
  cancelled = true;
4265
5562
  };
4266
5563
  }, [baseUrl, token]);
4267
- useEffect3(() => {
5564
+ useEffect5(() => {
4268
5565
  try {
4269
5566
  if (typeof window === "undefined") return;
4270
5567
  const handleKeyDown = (e) => {
@@ -4278,7 +5575,7 @@ function GlitchgrabProviderInner({
4278
5575
  } catch (e) {
4279
5576
  }
4280
5577
  }, [openReportDialog]);
4281
- const reporter = useMemo(() => {
5578
+ const reporter = useMemo2(() => {
4282
5579
  var _a;
4283
5580
  if (!session) return null;
4284
5581
  const avatar = (_a = session.avatarUrl) != null ? _a : session.image;
@@ -4288,11 +5585,11 @@ function GlitchgrabProviderInner({
4288
5585
  avatarUrl: typeof avatar === "string" ? avatar : null
4289
5586
  };
4290
5587
  }, [session]);
4291
- const [shortcutLabel, setShortcutLabel] = useState3(GLITCHGRAB_SHORTCUT2);
4292
- useEffect3(() => {
5588
+ const [shortcutLabel, setShortcutLabel] = useState5(GLITCHGRAB_SHORTCUT2);
5589
+ useEffect5(() => {
4293
5590
  setShortcutLabel(getShortcutLabel2());
4294
5591
  }, []);
4295
- return /* @__PURE__ */ jsxs3(
5592
+ return /* @__PURE__ */ jsxs5(
4296
5593
  GlitchgrabContext.Provider,
4297
5594
  {
4298
5595
  value: {
@@ -4307,11 +5604,12 @@ function GlitchgrabProviderInner({
4307
5604
  openFeedbackDialog,
4308
5605
  addBreadcrumb: addBreadcrumb2,
4309
5606
  openReportDialog,
5607
+ openBookingDialog,
4310
5608
  enhanceText: enhance,
4311
5609
  shortcutLabel
4312
5610
  },
4313
5611
  children: [
4314
- /* @__PURE__ */ jsx3(
5612
+ /* @__PURE__ */ jsx5(
4315
5613
  GlitchgrabErrorBoundary,
4316
5614
  {
4317
5615
  token,
@@ -4323,19 +5621,29 @@ function GlitchgrabProviderInner({
4323
5621
  children
4324
5622
  }
4325
5623
  ),
4326
- /* @__PURE__ */ jsx3(
5624
+ /* @__PURE__ */ jsx5(
5625
+ BookingDialog,
5626
+ {
5627
+ token,
5628
+ baseUrl: baseUrl != null ? baseUrl : DEFAULT_BASE_URL2,
5629
+ open: bookingOpen,
5630
+ onClose: () => setBookingOpen(false)
5631
+ }
5632
+ ),
5633
+ /* @__PURE__ */ jsx5(
4327
5634
  ReportDialog,
4328
5635
  {
4329
5636
  report,
4330
5637
  sendFeedback: feedback,
4331
5638
  enhanceText: enhance,
5639
+ assist: aiAssist ? assist : void 0,
4332
5640
  transcribeAudio: transcribe,
4333
5641
  types,
4334
5642
  showSeverity,
4335
5643
  reporter,
4336
- headerSlot: projectName ? /* @__PURE__ */ jsxs3("div", { style: { fontSize: 11, color: "#9aa0a6" }, children: [
5644
+ headerSlot: projectName ? /* @__PURE__ */ jsxs5("div", { style: { fontSize: 11, color: "#9aa0a6" }, children: [
4337
5645
  "Reporting to ",
4338
- /* @__PURE__ */ jsx3("strong", { style: { color: "#e5e5e5" }, children: projectName })
5646
+ /* @__PURE__ */ jsx5("strong", { style: { color: "#e5e5e5" }, children: projectName })
4339
5647
  ] }) : null
4340
5648
  }
4341
5649
  )
@@ -4344,21 +5652,21 @@ function GlitchgrabProviderInner({
4344
5652
  );
4345
5653
  }
4346
5654
  function GlitchgrabProvider(props) {
4347
- if (!props.token) return /* @__PURE__ */ jsx3(Fragment2, { children: props.children });
5655
+ if (!props.token) return /* @__PURE__ */ jsx5(Fragment4, { children: props.children });
4348
5656
  const resolvedProps = {
4349
5657
  ...props,
4350
5658
  baseUrl: props.baseUrl || DEFAULT_BASE_URL2
4351
5659
  };
4352
5660
  try {
4353
- return /* @__PURE__ */ jsx3(GlitchgrabProviderInner, { ...resolvedProps });
5661
+ return /* @__PURE__ */ jsx5(GlitchgrabProviderInner, { ...resolvedProps });
4354
5662
  } catch (e) {
4355
- return /* @__PURE__ */ jsx3(Fragment2, { children: props.children });
5663
+ return /* @__PURE__ */ jsx5(Fragment4, { children: props.children });
4356
5664
  }
4357
5665
  }
4358
5666
 
4359
5667
  // src/report-button.tsx
4360
- import { useState as useState4 } from "react";
4361
- import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
5668
+ import { useState as useState6 } from "react";
5669
+ import { Fragment as Fragment5, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
4362
5670
  function useGlitchgrabSafe() {
4363
5671
  try {
4364
5672
  return useGlitchgrab();
@@ -4373,7 +5681,7 @@ function ReportButton({
4373
5681
  children
4374
5682
  }) {
4375
5683
  var _a, _b;
4376
- const [capturing, setCapturing] = useState4(false);
5684
+ const [capturing, setCapturing] = useState6(false);
4377
5685
  const glitchgrab = useGlitchgrabSafe();
4378
5686
  if (!glitchgrab) return null;
4379
5687
  const handleClick = async () => {
@@ -4382,7 +5690,7 @@ function ReportButton({
4382
5690
  setCapturing(false);
4383
5691
  };
4384
5692
  if (children) {
4385
- return /* @__PURE__ */ jsx4(Fragment3, { children: children({ onClick: handleClick, capturing }) });
5693
+ return /* @__PURE__ */ jsx6(Fragment5, { children: children({ onClick: handleClick, capturing }) });
4386
5694
  }
4387
5695
  const isTop = (_a = position == null ? void 0 : position.startsWith("top")) != null ? _a : false;
4388
5696
  const isLeft = (_b = position == null ? void 0 : position.endsWith("left")) != null ? _b : false;
@@ -4390,7 +5698,7 @@ function ReportButton({
4390
5698
  ...isLeft ? { left: "16px" } : { right: "16px" },
4391
5699
  ...isTop ? { top: "16px" } : { bottom: "16px" }
4392
5700
  };
4393
- return /* @__PURE__ */ jsxs4(
5701
+ return /* @__PURE__ */ jsxs6(
4394
5702
  "button",
4395
5703
  {
4396
5704
  type: "button",
@@ -4425,7 +5733,7 @@ function ReportButton({
4425
5733
  },
4426
5734
  "aria-label": label,
4427
5735
  children: [
4428
- /* @__PURE__ */ jsx4(
5736
+ /* @__PURE__ */ jsx6(
4429
5737
  "svg",
4430
5738
  {
4431
5739
  width: "16",
@@ -4433,7 +5741,7 @@ function ReportButton({
4433
5741
  viewBox: "0 0 16 16",
4434
5742
  fill: "none",
4435
5743
  style: { flexShrink: 0 },
4436
- children: /* @__PURE__ */ jsx4(
5744
+ children: /* @__PURE__ */ jsx6(
4437
5745
  "path",
4438
5746
  {
4439
5747
  d: "M8 1C4.134 1 1 4.134 1 8s3.134 7 7 7 7-3.134 7-7-3.134-7-7-7zm0 12.5a.75.75 0 110-1.5.75.75 0 010 1.5zm.75-3.5a.75.75 0 01-1.5 0V5a.75.75 0 011.5 0v5z",
@@ -4448,8 +5756,38 @@ function ReportButton({
4448
5756
  );
4449
5757
  }
4450
5758
 
5759
+ // src/book-demo-button.tsx
5760
+ import { Fragment as Fragment6, jsx as jsx7 } from "react/jsx-runtime";
5761
+ function BookDemoButton({
5762
+ label = "Book a demo",
5763
+ className,
5764
+ children
5765
+ }) {
5766
+ const { openBookingDialog } = useGlitchgrab();
5767
+ if (children) return /* @__PURE__ */ jsx7(Fragment6, { children: children({ onClick: openBookingDialog }) });
5768
+ return /* @__PURE__ */ jsx7(
5769
+ "button",
5770
+ {
5771
+ type: "button",
5772
+ onClick: openBookingDialog,
5773
+ className,
5774
+ style: className ? void 0 : {
5775
+ padding: "10px 18px",
5776
+ borderRadius: 999,
5777
+ border: 0,
5778
+ background: "#3b82f6",
5779
+ color: "#fff",
5780
+ fontSize: 14,
5781
+ fontWeight: 500,
5782
+ cursor: "pointer"
5783
+ },
5784
+ children: label
5785
+ }
5786
+ );
5787
+ }
5788
+
4451
5789
  // src/feedback-button.tsx
4452
- import { Fragment as Fragment4, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
5790
+ import { Fragment as Fragment7, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
4453
5791
  function useGlitchgrabSafe2() {
4454
5792
  try {
4455
5793
  return useGlitchgrab();
@@ -4468,7 +5806,7 @@ function FeedbackButton({
4468
5806
  if (!glitchgrab) return null;
4469
5807
  const handleClick = () => glitchgrab.openFeedbackDialog();
4470
5808
  if (children) {
4471
- return /* @__PURE__ */ jsx5(Fragment4, { children: children({ onClick: handleClick }) });
5809
+ return /* @__PURE__ */ jsx8(Fragment7, { children: children({ onClick: handleClick }) });
4472
5810
  }
4473
5811
  const isTop = (_a = position == null ? void 0 : position.startsWith("top")) != null ? _a : false;
4474
5812
  const isLeft = (_b = position == null ? void 0 : position.endsWith("left")) != null ? _b : false;
@@ -4476,7 +5814,7 @@ function FeedbackButton({
4476
5814
  ...isLeft ? { left: "16px" } : { right: "16px" },
4477
5815
  ...isTop ? { top: "16px" } : { bottom: "16px" }
4478
5816
  };
4479
- return /* @__PURE__ */ jsxs5(
5817
+ return /* @__PURE__ */ jsxs7(
4480
5818
  "button",
4481
5819
  {
4482
5820
  type: "button",
@@ -4509,7 +5847,7 @@ function FeedbackButton({
4509
5847
  },
4510
5848
  "aria-label": label,
4511
5849
  children: [
4512
- /* @__PURE__ */ jsx5(
5850
+ /* @__PURE__ */ jsx8(
4513
5851
  "svg",
4514
5852
  {
4515
5853
  width: "16",
@@ -4518,7 +5856,7 @@ function FeedbackButton({
4518
5856
  fill: "none",
4519
5857
  style: { flexShrink: 0 },
4520
5858
  "aria-hidden": "true",
4521
- children: /* @__PURE__ */ jsx5(
5859
+ children: /* @__PURE__ */ jsx8(
4522
5860
  "path",
4523
5861
  {
4524
5862
  d: "M12 2.5l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.4l-5.8 3 1.1-6.5L2.6 9.3l6.5-.9L12 2.5z",
@@ -4534,18 +5872,18 @@ function FeedbackButton({
4534
5872
  }
4535
5873
 
4536
5874
  // src/use-reports.ts
4537
- import { useState as useState5, useEffect as useEffect4, useCallback as useCallback2 } from "react";
5875
+ import { useState as useState7, useEffect as useEffect6, useCallback as useCallback3 } from "react";
4538
5876
  var BASE_URL = "https://glitchgrab.dev";
4539
5877
  function useGlitchgrabReports({
4540
5878
  token,
4541
5879
  userId,
4542
5880
  limit = 100
4543
5881
  }) {
4544
- const [reports, setReports] = useState5([]);
4545
- const [isLoading, setIsLoading] = useState5(true);
4546
- const [isFetching, setIsFetching] = useState5(false);
4547
- const [error, setError] = useState5(null);
4548
- const fetchReports = useCallback2(async () => {
5882
+ const [reports, setReports] = useState7([]);
5883
+ const [isLoading, setIsLoading] = useState7(true);
5884
+ const [isFetching, setIsFetching] = useState7(false);
5885
+ const [error, setError] = useState7(null);
5886
+ const fetchReports = useCallback3(async () => {
4549
5887
  var _a, _b;
4550
5888
  if (!token || !userId) {
4551
5889
  setIsLoading(false);
@@ -4571,7 +5909,7 @@ function useGlitchgrabReports({
4571
5909
  setIsFetching(false);
4572
5910
  }
4573
5911
  }, [token, userId, limit]);
4574
- useEffect4(() => {
5912
+ useEffect6(() => {
4575
5913
  fetchReports();
4576
5914
  }, [fetchReports]);
4577
5915
  return { reports, isLoading, isFetching, error, refetch: fetchReports };
@@ -4608,9 +5946,9 @@ function useGlitchgrabActions({
4608
5946
  onSuccess,
4609
5947
  onError
4610
5948
  }) {
4611
- const [isPending, setIsPending] = useState5(false);
4612
- const [error, setError] = useState5(null);
4613
- const run = useCallback2(
5949
+ const [isPending, setIsPending] = useState7(false);
5950
+ const [error, setError] = useState7(null);
5951
+ const run = useCallback3(
4614
5952
  async (reportId, body) => {
4615
5953
  setIsPending(true);
4616
5954
  setError(null);
@@ -4640,7 +5978,7 @@ function useGlitchgrabActions({
4640
5978
  }
4641
5979
 
4642
5980
  // src/use-feedback.ts
4643
- import { useState as useState6, useEffect as useEffect5, useCallback as useCallback3 } from "react";
5981
+ import { useState as useState8, useEffect as useEffect7, useCallback as useCallback4 } from "react";
4644
5982
  var DEFAULT_BASE_URL3 = "https://glitchgrab.dev";
4645
5983
  function buildUrl({
4646
5984
  approvedOnly,
@@ -4666,11 +6004,11 @@ async function fetchGlitchgrabFeedback(query) {
4666
6004
  }
4667
6005
  function useGlitchgrabFeedback(query) {
4668
6006
  const { token, approvedOnly, userId, minRating, limit, baseUrl } = query;
4669
- const [feedback, setFeedback] = useState6([]);
4670
- const [isLoading, setIsLoading] = useState6(true);
4671
- const [isFetching, setIsFetching] = useState6(false);
4672
- const [error, setError] = useState6(null);
4673
- const load = useCallback3(async () => {
6007
+ const [feedback, setFeedback] = useState8([]);
6008
+ const [isLoading, setIsLoading] = useState8(true);
6009
+ const [isFetching, setIsFetching] = useState8(false);
6010
+ const [error, setError] = useState8(null);
6011
+ const load = useCallback4(async () => {
4674
6012
  if (!token) {
4675
6013
  setIsLoading(false);
4676
6014
  return;
@@ -4694,12 +6032,13 @@ function useGlitchgrabFeedback(query) {
4694
6032
  setIsFetching(false);
4695
6033
  }
4696
6034
  }, [token, approvedOnly, userId, minRating, limit, baseUrl]);
4697
- useEffect5(() => {
6035
+ useEffect7(() => {
4698
6036
  load();
4699
6037
  }, [load]);
4700
6038
  return { feedback, isLoading, isFetching, error, refetch: load };
4701
6039
  }
4702
6040
  export {
6041
+ BookDemoButton,
4703
6042
  FeedbackButton,
4704
6043
  GLITCHGRAB_SHORTCUT2 as GLITCHGRAB_SHORTCUT,
4705
6044
  GLITCHGRAB_SHORTCUT_MAC2 as GLITCHGRAB_SHORTCUT_MAC,