glitchgrab 1.34.0 → 1.36.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.js CHANGED
@@ -68,7 +68,7 @@ __export(index_exports, {
68
68
  module.exports = __toCommonJS(index_exports);
69
69
 
70
70
  // src/provider.tsx
71
- var import_react4 = require("react");
71
+ var import_react5 = require("react");
72
72
 
73
73
  // src/error-boundary.tsx
74
74
  var React = __toESM(require("react"));
@@ -646,6 +646,46 @@ async function enhanceText(text, token, baseUrl, screenshot, context) {
646
646
  return text;
647
647
  }
648
648
  }
649
+ async function assistTurn(params, token, baseUrl) {
650
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
651
+ const offline = {
652
+ conversationId: null,
653
+ question: null,
654
+ report: null,
655
+ degraded: "The assistant is unavailable \u2014 write your report below and send it as normal."
656
+ };
657
+ try {
658
+ const url = `${baseUrl != null ? baseUrl : DEFAULT_BASE_URL}/api/v1/ai/report-chat`;
659
+ const response = await fetch(url, {
660
+ method: "POST",
661
+ headers: {
662
+ "Content-Type": "application/json",
663
+ Authorization: `Bearer ${token}`
664
+ },
665
+ body: JSON.stringify(params)
666
+ });
667
+ const envelope = await response.json().catch(() => null);
668
+ if (!response.ok || !(envelope == null ? void 0 : envelope.success)) {
669
+ return {
670
+ conversationId: null,
671
+ question: null,
672
+ report: null,
673
+ degraded: (_a = envelope == null ? void 0 : envelope.error) != null ? _a : offline.degraded
674
+ };
675
+ }
676
+ return {
677
+ conversationId: (_c = (_b = envelope.data) == null ? void 0 : _b.conversationId) != null ? _c : null,
678
+ question: (_e = (_d = envelope.data) == null ? void 0 : _d.question) != null ? _e : null,
679
+ options: (_g = (_f = envelope.data) == null ? void 0 : _f.options) != null ? _g : [],
680
+ report: (_i = (_h = envelope.data) == null ? void 0 : _h.report) != null ? _i : null,
681
+ duplicate: (_k = (_j = envelope.data) == null ? void 0 : _j.duplicate) != null ? _k : null,
682
+ solved: (_m = (_l = envelope.data) == null ? void 0 : _l.solved) != null ? _m : null,
683
+ degraded: null
684
+ };
685
+ } catch (e) {
686
+ return offline;
687
+ }
688
+ }
649
689
  async function transcribeAudio(blob, token, baseUrl) {
650
690
  var _a;
651
691
  try {
@@ -857,7 +897,10 @@ var import_react = require("react");
857
897
  var import_react_dom = require("react-dom");
858
898
  var import_react2 = require("react");
859
899
  var import_jsx_runtime = require("react/jsx-runtime");
900
+ var import_react3 = require("react");
901
+ var import_react_dom2 = require("react-dom");
860
902
  var import_jsx_runtime2 = require("react/jsx-runtime");
903
+ var import_jsx_runtime3 = require("react/jsx-runtime");
861
904
  var MAX_SCREENSHOT_DATA_URL_LENGTH = 18e5;
862
905
  var QUALITY_LADDER = [0.92, 0.85, 0.75];
863
906
  var DOWNSCALE_FACTOR = 0.7;
@@ -1158,9 +1201,1058 @@ function AnnotationCanvas({ imageSrc, onSave, onCancel }) {
1158
1201
  children: "Save annotation"
1159
1202
  }
1160
1203
  )
1161
- ] })
1162
- ]
1163
- }
1204
+ ] })
1205
+ ]
1206
+ }
1207
+ );
1208
+ }
1209
+ function getTypeLabel(type) {
1210
+ switch (type) {
1211
+ case "RATING":
1212
+ return "Rating";
1213
+ case "BUG":
1214
+ return "Bug Report";
1215
+ case "FEATURE_REQUEST":
1216
+ return "Feature Request";
1217
+ case "UI_IMPROVEMENT":
1218
+ return "UI Improvement";
1219
+ case "PERFORMANCE":
1220
+ return "Performance";
1221
+ case "SECURITY":
1222
+ return "Security";
1223
+ case "QUESTION":
1224
+ return "Question";
1225
+ case "OTHER":
1226
+ return "Other";
1227
+ }
1228
+ }
1229
+ var STARTERS = [
1230
+ "Something on this page is broken",
1231
+ "It did the wrong thing",
1232
+ "I wish it could\u2026"
1233
+ ];
1234
+ var NARROW_QUERY = "(max-width: 640px)";
1235
+ function useIsNarrow() {
1236
+ const [narrow, setNarrow] = (0, import_react3.useState)(false);
1237
+ (0, import_react3.useEffect)(() => {
1238
+ try {
1239
+ const mq = window.matchMedia(NARROW_QUERY);
1240
+ setNarrow(mq.matches);
1241
+ const onChange = (e) => setNarrow(e.matches);
1242
+ mq.addEventListener("change", onChange);
1243
+ return () => mq.removeEventListener("change", onChange);
1244
+ } catch (e) {
1245
+ }
1246
+ }, []);
1247
+ return narrow;
1248
+ }
1249
+ function Sparkle({ color, size = 14 }) {
1250
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1251
+ "path",
1252
+ {
1253
+ 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",
1254
+ stroke: color,
1255
+ strokeWidth: "1.5",
1256
+ strokeLinejoin: "round"
1257
+ }
1258
+ ) });
1259
+ }
1260
+ function Avatar({
1261
+ who,
1262
+ theme: t2,
1263
+ initials
1264
+ }) {
1265
+ const isAi = who === "assistant";
1266
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1267
+ "span",
1268
+ {
1269
+ "aria-hidden": "true",
1270
+ style: {
1271
+ flexShrink: 0,
1272
+ width: "24px",
1273
+ height: "24px",
1274
+ borderRadius: "50%",
1275
+ display: "inline-flex",
1276
+ alignItems: "center",
1277
+ justifyContent: "center",
1278
+ marginTop: "2px",
1279
+ backgroundColor: isAi ? `${t2.accent}22` : t2.bgSecondary,
1280
+ border: `1px solid ${isAi ? t2.accent : t2.inputBorder}`,
1281
+ color: isAi ? t2.accent : t2.textMuted,
1282
+ fontSize: "10px",
1283
+ fontWeight: 700
1284
+ },
1285
+ children: isAi ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Sparkle, { color: t2.accent, size: 12 }) : initials ? initials : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: [
1286
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "12", cy: "8", r: "3.4", stroke: "currentColor", strokeWidth: "1.8" }),
1287
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1288
+ "path",
1289
+ {
1290
+ d: "M5 20c0-3.6 3.1-5.6 7-5.6s7 2 7 5.6",
1291
+ stroke: "currentColor",
1292
+ strokeWidth: "1.8",
1293
+ strokeLinecap: "round"
1294
+ }
1295
+ )
1296
+ ] })
1297
+ }
1298
+ );
1299
+ }
1300
+ function AssistSheet({
1301
+ assist,
1302
+ theme: t2,
1303
+ screenshot,
1304
+ attachmentCount,
1305
+ context,
1306
+ reportTypeLabel,
1307
+ typePicked,
1308
+ currentTile,
1309
+ tiles,
1310
+ onPickType,
1311
+ rating,
1312
+ onRatingChange,
1313
+ projectSlot,
1314
+ reporterName,
1315
+ description,
1316
+ onDescriptionChange,
1317
+ severity,
1318
+ onSeverityChange,
1319
+ showSeverity,
1320
+ onDuplicateChange,
1321
+ isSubmitting,
1322
+ submitted,
1323
+ onSend,
1324
+ onDegrade,
1325
+ onClose,
1326
+ onFinish
1327
+ }) {
1328
+ const narrow = useIsNarrow();
1329
+ const [messages, setMessages] = (0, import_react3.useState)([]);
1330
+ const [input, setInput] = (0, import_react3.useState)("");
1331
+ const [busy, setBusy] = (0, import_react3.useState)(false);
1332
+ const [conversationId, setConversationId] = (0, import_react3.useState)(null);
1333
+ const [hoveredStar, setHoveredStar] = (0, import_react3.useState)(0);
1334
+ const [options, setOptions] = (0, import_react3.useState)([]);
1335
+ const [duplicate, setDuplicate] = (0, import_react3.useState)(null);
1336
+ const [solved, setSolved] = (0, import_react3.useState)(null);
1337
+ const [phase, setPhase] = (0, import_react3.useState)(
1338
+ !typePicked ? "type" : currentTile === "RATING" ? "rating" : "chat"
1339
+ );
1340
+ const scrollRef = (0, import_react3.useRef)(null);
1341
+ const inputRef = (0, import_react3.useRef)(null);
1342
+ const draftRef = (0, import_react3.useRef)(null);
1343
+ const seededRef = (0, import_react3.useRef)(false);
1344
+ (0, import_react3.useEffect)(() => {
1345
+ const el = scrollRef.current;
1346
+ if (el) el.scrollTop = el.scrollHeight;
1347
+ }, [messages, busy, phase]);
1348
+ (0, import_react3.useEffect)(() => {
1349
+ var _a;
1350
+ if (phase === "draft") (_a = draftRef.current) == null ? void 0 : _a.focus();
1351
+ }, [phase]);
1352
+ async function runTurn(history2) {
1353
+ var _a, _b, _c, _d;
1354
+ setBusy(true);
1355
+ let result;
1356
+ try {
1357
+ result = await assist({ messages: history2, conversationId, screenshot, context });
1358
+ } catch (e) {
1359
+ onDegrade("The assistant is unavailable \u2014 write your report below and send it as normal.");
1360
+ return;
1361
+ } finally {
1362
+ setBusy(false);
1363
+ }
1364
+ if (result.degraded) {
1365
+ onDegrade(result.degraded);
1366
+ return;
1367
+ }
1368
+ if (result.conversationId) setConversationId(result.conversationId);
1369
+ setDuplicate((_a = result.duplicate) != null ? _a : null);
1370
+ onDuplicateChange == null ? void 0 : onDuplicateChange((_c = (_b = result.duplicate) == null ? void 0 : _b.number) != null ? _c : null);
1371
+ if (result.solved) {
1372
+ setSolved(result.solved);
1373
+ setOptions([]);
1374
+ setPhase("solved");
1375
+ return;
1376
+ }
1377
+ if (result.report) {
1378
+ onDescriptionChange(result.report);
1379
+ setMessages([...history2, { role: "assistant", content: "Here's your report \u2014 have a read." }]);
1380
+ setOptions([]);
1381
+ setPhase("draft");
1382
+ return;
1383
+ }
1384
+ if (result.question) {
1385
+ setMessages([...history2, { role: "assistant", content: result.question }]);
1386
+ setOptions((_d = result.options) != null ? _d : []);
1387
+ return;
1388
+ }
1389
+ onDegrade("The assistant had nothing to add \u2014 write your report below and send it as normal.");
1390
+ }
1391
+ (0, import_react3.useEffect)(() => {
1392
+ if (seededRef.current) return;
1393
+ seededRef.current = true;
1394
+ if (!typePicked || currentTile === "RATING") return;
1395
+ const seed = description.trim();
1396
+ if (!seed) return;
1397
+ const history2 = [{ role: "user", content: seed }];
1398
+ setMessages(history2);
1399
+ void runTurn(history2);
1400
+ }, []);
1401
+ function send(text) {
1402
+ const value = text.trim();
1403
+ if (!value || busy) return;
1404
+ setOptions([]);
1405
+ const history2 = [...messages, { role: "user", content: value }];
1406
+ setMessages(history2);
1407
+ setInput("");
1408
+ void runTurn(history2);
1409
+ }
1410
+ function pickType(tile) {
1411
+ onPickType(tile);
1412
+ setPhase(tile === "RATING" ? "rating" : "chat");
1413
+ }
1414
+ const empty = phase === "chat" && messages.length === 0 && !busy;
1415
+ const initials = (reporterName != null ? reporterName : "").split(/\s+/).filter(Boolean).slice(0, 2).map((w) => {
1416
+ var _a, _b;
1417
+ return (_b = (_a = w[0]) == null ? void 0 : _a.toUpperCase()) != null ? _b : "";
1418
+ }).join("");
1419
+ const panelStyle = narrow ? {
1420
+ width: "100%",
1421
+ maxHeight: "88dvh",
1422
+ borderTopLeftRadius: "16px",
1423
+ borderTopRightRadius: "16px",
1424
+ animation: "gg-sheet-up .22s cubic-bezier(.2,.8,.2,1)"
1425
+ } : {
1426
+ width: "440px",
1427
+ maxWidth: "100%",
1428
+ height: "100dvh",
1429
+ borderLeft: `1px solid ${t2.border}`,
1430
+ animation: "gg-sheet-in .22s cubic-bezier(.2,.8,.2,1)"
1431
+ };
1432
+ return (0, import_react_dom2.createPortal)(
1433
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
1434
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("style", { children: `
1435
+ @keyframes gg-sheet-in{from{transform:translateX(24px);opacity:0}to{transform:translateX(0);opacity:1}}
1436
+ @keyframes gg-sheet-up{from{transform:translateY(24px);opacity:0}to{transform:translateY(0);opacity:1}}
1437
+ @keyframes gg-sheet-fade{from{opacity:0}to{opacity:1}}
1438
+ @keyframes gg-dot{0%,80%,100%{transform:translateY(0);opacity:.4}40%{transform:translateY(-3px);opacity:1}}
1439
+ [data-gg-sheet-send]:focus-visible,[data-gg-chip]:focus-visible{outline:2px solid currentColor;outline-offset:2px}
1440
+ ` }),
1441
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1442
+ "div",
1443
+ {
1444
+ "data-glitchgrab-layer": "",
1445
+ role: "dialog",
1446
+ "aria-modal": "true",
1447
+ "aria-label": "Describe your report with AI",
1448
+ style: {
1449
+ position: "fixed",
1450
+ inset: 0,
1451
+ zIndex: 2147483647,
1452
+ display: "flex",
1453
+ alignItems: narrow ? "flex-end" : "stretch",
1454
+ justifyContent: narrow ? "center" : "flex-end",
1455
+ backgroundColor: "rgba(0,0,0,0.5)",
1456
+ animation: "gg-sheet-fade .18s ease",
1457
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
1458
+ },
1459
+ onClick: onClose,
1460
+ onPointerDown: (e) => e.stopPropagation(),
1461
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1462
+ "div",
1463
+ {
1464
+ onClick: (e) => e.stopPropagation(),
1465
+ style: {
1466
+ ...panelStyle,
1467
+ display: "flex",
1468
+ flexDirection: "column",
1469
+ // A flex child defaults to min-width:auto, so a long chat bubble
1470
+ // grows the sheet past the viewport instead of wrapping inside it.
1471
+ // This is what keeps the bottom sheet on screen.
1472
+ minWidth: 0,
1473
+ maxWidth: "100%",
1474
+ boxSizing: "border-box",
1475
+ backgroundColor: t2.bg,
1476
+ color: t2.text,
1477
+ boxShadow: "0 20px 60px rgba(0,0,0,.35)",
1478
+ overflow: "hidden",
1479
+ isolation: "isolate"
1480
+ },
1481
+ children: [
1482
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1483
+ "div",
1484
+ {
1485
+ style: {
1486
+ flexShrink: 0,
1487
+ padding: "14px 16px",
1488
+ borderBottom: `1px solid ${t2.border}`,
1489
+ display: "flex",
1490
+ alignItems: "flex-start",
1491
+ justifyContent: "space-between",
1492
+ gap: "12px",
1493
+ minWidth: 0
1494
+ },
1495
+ children: [
1496
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { minWidth: 0, overflow: "hidden" }, children: [
1497
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1498
+ "div",
1499
+ {
1500
+ style: {
1501
+ display: "flex",
1502
+ alignItems: "center",
1503
+ gap: "7px",
1504
+ fontSize: "14px",
1505
+ fontWeight: 600
1506
+ },
1507
+ children: [
1508
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Sparkle, { color: t2.accent }),
1509
+ "Describe it with AI",
1510
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1511
+ "span",
1512
+ {
1513
+ style: {
1514
+ fontSize: "10px",
1515
+ fontWeight: 600,
1516
+ letterSpacing: ".04em",
1517
+ textTransform: "uppercase",
1518
+ color: t2.accent,
1519
+ border: `1px solid ${t2.accent}55`,
1520
+ borderRadius: "4px",
1521
+ padding: "1px 5px"
1522
+ },
1523
+ children: "Beta"
1524
+ }
1525
+ )
1526
+ ]
1527
+ }
1528
+ ),
1529
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { fontSize: "11.5px", color: t2.textMuted, marginTop: "3px" }, children: [
1530
+ phase === "type" ? null : reportTypeLabel,
1531
+ projectSlot ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { marginLeft: "6px" }, children: projectSlot }) : null
1532
+ ] })
1533
+ ] }),
1534
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1535
+ "button",
1536
+ {
1537
+ type: "button",
1538
+ onClick: onClose,
1539
+ "aria-label": "Close and write it myself",
1540
+ style: {
1541
+ flexShrink: 0,
1542
+ border: "none",
1543
+ background: "transparent",
1544
+ color: t2.textMuted,
1545
+ cursor: "pointer",
1546
+ fontSize: narrow ? "18px" : "12px",
1547
+ lineHeight: 1,
1548
+ fontFamily: "inherit",
1549
+ padding: narrow ? "4px 6px" : "6px 4px"
1550
+ },
1551
+ children: narrow ? "\xD7" : "Write it myself"
1552
+ }
1553
+ )
1554
+ ]
1555
+ }
1556
+ ),
1557
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1558
+ "div",
1559
+ {
1560
+ ref: scrollRef,
1561
+ style: {
1562
+ flex: 1,
1563
+ minHeight: narrow ? "180px" : 0,
1564
+ overflowY: "auto",
1565
+ padding: "16px",
1566
+ display: "flex",
1567
+ flexDirection: "column"
1568
+ },
1569
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1570
+ "div",
1571
+ {
1572
+ style: {
1573
+ marginTop: "auto",
1574
+ display: "flex",
1575
+ flexDirection: "column",
1576
+ gap: "12px",
1577
+ minWidth: 0
1578
+ },
1579
+ children: [
1580
+ phase === "type" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
1581
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: "8px" }, children: [
1582
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Avatar, { who: "assistant", theme: t2 }),
1583
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1584
+ "div",
1585
+ {
1586
+ style: {
1587
+ padding: "9px 12px",
1588
+ borderRadius: "12px 12px 12px 4px",
1589
+ backgroundColor: t2.bgSecondary,
1590
+ fontSize: "13px",
1591
+ lineHeight: 1.55,
1592
+ maxWidth: "88%"
1593
+ },
1594
+ children: [
1595
+ reporterName ? `Hi ${reporterName.split(" ")[0]} \u2014 w` : "W",
1596
+ "hat do you want to do? Pick one and I'll take it from there."
1597
+ ]
1598
+ }
1599
+ )
1600
+ ] }),
1601
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1602
+ "div",
1603
+ {
1604
+ style: {
1605
+ display: "flex",
1606
+ flexWrap: "wrap",
1607
+ gap: "6px",
1608
+ paddingLeft: "32px"
1609
+ },
1610
+ children: tiles.map((tile) => {
1611
+ const rate = tile === "RATING";
1612
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1613
+ "button",
1614
+ {
1615
+ type: "button",
1616
+ "data-gg-chip": "",
1617
+ "data-gg-tile": tile,
1618
+ onClick: () => pickType(tile),
1619
+ style: {
1620
+ display: "inline-flex",
1621
+ alignItems: "center",
1622
+ gap: "5px",
1623
+ // The rating is the only tile that isn't a report, so
1624
+ // it wears the star colour the dialog's hero row uses
1625
+ // rather than hiding among the report types.
1626
+ border: `1px solid ${rate ? "rgba(245,158,11,0.5)" : t2.inputBorder}`,
1627
+ background: rate ? "rgba(245,158,11,0.08)" : "transparent",
1628
+ color: rate ? "#f59e0b" : t2.textMuted,
1629
+ borderRadius: "999px",
1630
+ // 8px vertical keeps the tap target at ~32px.
1631
+ padding: "8px 12px",
1632
+ fontSize: "12px",
1633
+ fontWeight: rate ? 600 : 400,
1634
+ fontFamily: "inherit",
1635
+ cursor: "pointer"
1636
+ },
1637
+ children: rate ? "\u2605 Rate us" : getTypeLabel(tile)
1638
+ },
1639
+ tile
1640
+ );
1641
+ })
1642
+ }
1643
+ )
1644
+ ] }),
1645
+ phase === "rating" && !submitted && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
1646
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: "8px" }, children: [
1647
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Avatar, { who: "assistant", theme: t2 }),
1648
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1649
+ "div",
1650
+ {
1651
+ style: {
1652
+ padding: "9px 12px",
1653
+ borderRadius: "12px 12px 12px 4px",
1654
+ backgroundColor: t2.bgSecondary,
1655
+ fontSize: "13px",
1656
+ lineHeight: 1.55,
1657
+ maxWidth: "88%"
1658
+ },
1659
+ children: "How are we doing? Tap a star \u2014 the words are optional."
1660
+ }
1661
+ )
1662
+ ] }),
1663
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1664
+ "div",
1665
+ {
1666
+ style: {
1667
+ display: "flex",
1668
+ flexDirection: "column",
1669
+ gap: "10px",
1670
+ marginLeft: "32px",
1671
+ padding: "12px",
1672
+ borderRadius: "12px",
1673
+ border: "1px solid rgba(245,158,11,0.4)",
1674
+ backgroundColor: "rgba(245,158,11,0.06)"
1675
+ },
1676
+ children: [
1677
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", gap: "4px" }, role: "group", "aria-label": "Rating", children: [1, 2, 3, 4, 5].map((star) => {
1678
+ const filled = star <= (hoveredStar || rating);
1679
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1680
+ "button",
1681
+ {
1682
+ type: "button",
1683
+ "aria-label": `${star} star${star > 1 ? "s" : ""}`,
1684
+ "aria-pressed": star <= rating,
1685
+ onClick: () => onRatingChange(star),
1686
+ onMouseEnter: () => setHoveredStar(star),
1687
+ onMouseLeave: () => setHoveredStar(0),
1688
+ style: {
1689
+ border: "none",
1690
+ background: "transparent",
1691
+ padding: 0,
1692
+ cursor: "pointer",
1693
+ lineHeight: 0
1694
+ },
1695
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "30", height: "30", viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1696
+ "path",
1697
+ {
1698
+ 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",
1699
+ fill: filled ? "#f59e0b" : "transparent",
1700
+ stroke: filled ? "#f59e0b" : t2.inputBorder,
1701
+ strokeWidth: "1.5",
1702
+ strokeLinejoin: "round"
1703
+ }
1704
+ ) })
1705
+ },
1706
+ star
1707
+ );
1708
+ }) }),
1709
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1710
+ "textarea",
1711
+ {
1712
+ value: description,
1713
+ onChange: (e) => onDescriptionChange(e.target.value),
1714
+ rows: 3,
1715
+ placeholder: "What made it good \u2014 or what let you down? (optional)",
1716
+ style: {
1717
+ width: "100%",
1718
+ padding: "10px",
1719
+ borderRadius: "8px",
1720
+ border: `1px solid ${t2.inputBorder}`,
1721
+ backgroundColor: t2.inputBg,
1722
+ color: t2.text,
1723
+ fontSize: "13px",
1724
+ lineHeight: 1.5,
1725
+ fontFamily: "inherit",
1726
+ resize: "vertical",
1727
+ outline: "none",
1728
+ boxSizing: "border-box"
1729
+ }
1730
+ }
1731
+ ),
1732
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1733
+ "button",
1734
+ {
1735
+ type: "button",
1736
+ onClick: () => setPhase("type"),
1737
+ style: {
1738
+ alignSelf: "flex-start",
1739
+ border: "none",
1740
+ background: "transparent",
1741
+ color: t2.textMuted,
1742
+ fontSize: "12px",
1743
+ fontFamily: "inherit",
1744
+ // A bare text link is ~14px tall — half a thumb.
1745
+ padding: "9px 0",
1746
+ cursor: "pointer",
1747
+ textDecoration: "underline"
1748
+ },
1749
+ children: "Report something instead"
1750
+ }
1751
+ )
1752
+ ]
1753
+ }
1754
+ )
1755
+ ] }),
1756
+ empty && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
1757
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: "8px" }, children: [
1758
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Avatar, { who: "assistant", theme: t2 }),
1759
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1760
+ "div",
1761
+ {
1762
+ style: {
1763
+ padding: "9px 12px",
1764
+ borderRadius: "12px 12px 12px 4px",
1765
+ backgroundColor: t2.bgSecondary,
1766
+ fontSize: "13px",
1767
+ lineHeight: 1.55,
1768
+ maxWidth: "88%"
1769
+ },
1770
+ children: [
1771
+ reporterName ? `Hi ${reporterName.split(" ")[0]} \u2014 t` : "T",
1772
+ "ell me what went wrong in your own words. I can already see your screenshot and what you clicked, so skip the boring parts."
1773
+ ]
1774
+ }
1775
+ )
1776
+ ] }),
1777
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1778
+ "div",
1779
+ {
1780
+ style: {
1781
+ display: "flex",
1782
+ flexWrap: "wrap",
1783
+ gap: "6px",
1784
+ paddingLeft: "32px"
1785
+ },
1786
+ children: STARTERS.map((s) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1787
+ "button",
1788
+ {
1789
+ type: "button",
1790
+ "data-gg-chip": "",
1791
+ onClick: () => send(s),
1792
+ style: {
1793
+ border: `1px solid ${t2.inputBorder}`,
1794
+ background: "transparent",
1795
+ color: t2.textMuted,
1796
+ borderRadius: "999px",
1797
+ padding: "6px 11px",
1798
+ fontSize: "12px",
1799
+ fontFamily: "inherit",
1800
+ cursor: "pointer"
1801
+ },
1802
+ children: s
1803
+ },
1804
+ s
1805
+ ))
1806
+ }
1807
+ )
1808
+ ] }),
1809
+ messages.map((m, i) => {
1810
+ const mine = m.role === "user";
1811
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1812
+ "div",
1813
+ {
1814
+ style: {
1815
+ display: "flex",
1816
+ gap: "8px",
1817
+ minWidth: 0,
1818
+ flexDirection: mine ? "row-reverse" : "row"
1819
+ },
1820
+ children: [
1821
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Avatar, { who: m.role, theme: t2, initials }),
1822
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1823
+ "div",
1824
+ {
1825
+ style: {
1826
+ maxWidth: "82%",
1827
+ padding: "9px 12px",
1828
+ borderRadius: mine ? "12px 12px 4px 12px" : "12px 12px 12px 4px",
1829
+ fontSize: "13px",
1830
+ lineHeight: 1.55,
1831
+ whiteSpace: "pre-wrap",
1832
+ wordBreak: "break-word",
1833
+ backgroundColor: mine ? t2.accent : t2.bgSecondary,
1834
+ color: mine ? t2.accentText : t2.text
1835
+ },
1836
+ children: m.content
1837
+ }
1838
+ )
1839
+ ]
1840
+ },
1841
+ i
1842
+ );
1843
+ }),
1844
+ options.length > 0 && !busy && phase === "chat" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1845
+ "div",
1846
+ {
1847
+ style: {
1848
+ display: "flex",
1849
+ // Long labels wrapped into a ragged row that always stranded
1850
+ // the last chip on a line of its own. Past ~24 characters
1851
+ // these stop being chips and become a choice list, so they
1852
+ // stack full width and read like one.
1853
+ flexDirection: options.some((o) => o.length > 24) ? "column" : "row",
1854
+ alignItems: options.some((o) => o.length > 24) ? "stretch" : "flex-start",
1855
+ flexWrap: "wrap",
1856
+ gap: "6px",
1857
+ paddingLeft: "32px"
1858
+ },
1859
+ children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1860
+ "button",
1861
+ {
1862
+ type: "button",
1863
+ "data-gg-chip": "",
1864
+ "data-gg-option": "",
1865
+ onClick: () => send(option),
1866
+ style: {
1867
+ border: `1px solid ${t2.inputBorder}`,
1868
+ background: "transparent",
1869
+ color: t2.textMuted,
1870
+ borderRadius: "999px",
1871
+ // Same 8px as the picker chips — one tap target size in
1872
+ // this sheet, not two.
1873
+ padding: "8px 12px",
1874
+ fontSize: "12px",
1875
+ fontFamily: "inherit",
1876
+ cursor: "pointer",
1877
+ textAlign: "left"
1878
+ },
1879
+ children: option
1880
+ },
1881
+ option
1882
+ ))
1883
+ }
1884
+ ),
1885
+ busy && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: "8px" }, role: "status", "aria-label": "Thinking", children: [
1886
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Avatar, { who: "assistant", theme: t2 }),
1887
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1888
+ "span",
1889
+ {
1890
+ style: {
1891
+ display: "inline-flex",
1892
+ alignItems: "center",
1893
+ gap: "4px",
1894
+ padding: "12px",
1895
+ borderRadius: "12px 12px 12px 4px",
1896
+ backgroundColor: t2.bgSecondary
1897
+ },
1898
+ children: [0, 1, 2].map((i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1899
+ "span",
1900
+ {
1901
+ style: {
1902
+ width: "5px",
1903
+ height: "5px",
1904
+ borderRadius: "50%",
1905
+ backgroundColor: t2.textMuted,
1906
+ animation: `gg-dot 1.1s ease-in-out ${i * 0.15}s infinite`
1907
+ }
1908
+ },
1909
+ i
1910
+ ))
1911
+ }
1912
+ )
1913
+ ] }),
1914
+ phase === "draft" && !submitted && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1915
+ "div",
1916
+ {
1917
+ style: {
1918
+ border: `1px solid ${t2.accent}`,
1919
+ borderRadius: "12px",
1920
+ backgroundColor: t2.bgSecondary,
1921
+ padding: "12px",
1922
+ display: "flex",
1923
+ flexDirection: "column",
1924
+ gap: "10px",
1925
+ minWidth: 0,
1926
+ boxSizing: "border-box"
1927
+ },
1928
+ children: [
1929
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1930
+ "span",
1931
+ {
1932
+ style: {
1933
+ fontSize: "10px",
1934
+ fontWeight: 700,
1935
+ letterSpacing: ".06em",
1936
+ textTransform: "uppercase",
1937
+ color: t2.accent
1938
+ },
1939
+ children: "Your report \xB7 edit anything"
1940
+ }
1941
+ ),
1942
+ duplicate && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1943
+ "div",
1944
+ {
1945
+ style: {
1946
+ display: "flex",
1947
+ flexDirection: "column",
1948
+ gap: "3px",
1949
+ padding: "9px 10px",
1950
+ borderRadius: "8px",
1951
+ border: "1px solid rgba(245,158,11,0.4)",
1952
+ backgroundColor: "rgba(245,158,11,0.08)",
1953
+ fontSize: "12px",
1954
+ lineHeight: 1.5
1955
+ },
1956
+ children: [
1957
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: "#f59e0b", fontWeight: 600 }, children: "Our team is already on this" }),
1958
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: { color: t2.textMuted, wordBreak: "break-word" }, children: [
1959
+ "#",
1960
+ duplicate.number,
1961
+ " ",
1962
+ duplicate.title
1963
+ ] }),
1964
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: t2.textMuted }, children: "Your details will be added to it instead of opening a new issue." })
1965
+ ]
1966
+ }
1967
+ ),
1968
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1969
+ "textarea",
1970
+ {
1971
+ ref: draftRef,
1972
+ value: description,
1973
+ onChange: (e) => onDescriptionChange(e.target.value),
1974
+ rows: 6,
1975
+ style: {
1976
+ width: "100%",
1977
+ minHeight: "120px",
1978
+ padding: "10px",
1979
+ borderRadius: "8px",
1980
+ border: `1px solid ${t2.inputBorder}`,
1981
+ backgroundColor: t2.inputBg,
1982
+ color: t2.text,
1983
+ fontSize: "13px",
1984
+ lineHeight: 1.55,
1985
+ fontFamily: "inherit",
1986
+ resize: "vertical",
1987
+ outline: "none",
1988
+ boxSizing: "border-box"
1989
+ }
1990
+ }
1991
+ ),
1992
+ showSeverity && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
1993
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1994
+ "span",
1995
+ {
1996
+ style: {
1997
+ fontSize: "11.5px",
1998
+ color: t2.textMuted,
1999
+ display: "block",
2000
+ marginBottom: "6px"
2001
+ },
2002
+ children: "How bad is it?"
2003
+ }
2004
+ ),
2005
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", gap: "6px" }, children: ["low", "medium", "high"].map((s) => {
2006
+ const on = severity === s;
2007
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2008
+ "button",
2009
+ {
2010
+ type: "button",
2011
+ onClick: () => onSeverityChange(s),
2012
+ "aria-pressed": on,
2013
+ style: {
2014
+ flex: 1,
2015
+ minWidth: 0,
2016
+ padding: "8px 0",
2017
+ borderRadius: "8px",
2018
+ border: `1px solid ${on ? t2.accent : t2.inputBorder}`,
2019
+ backgroundColor: on ? t2.accent : "transparent",
2020
+ color: on ? t2.accentText : t2.textMuted,
2021
+ fontSize: "12px",
2022
+ fontWeight: 600,
2023
+ fontFamily: "inherit",
2024
+ textTransform: "capitalize",
2025
+ cursor: "pointer"
2026
+ },
2027
+ children: s
2028
+ },
2029
+ s
2030
+ );
2031
+ }) })
2032
+ ] }),
2033
+ attachmentCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: { fontSize: "11.5px", color: t2.textMuted }, children: [
2034
+ attachmentCount,
2035
+ " ",
2036
+ attachmentCount === 1 ? "attachment" : "attachments",
2037
+ " will be sent with this."
2038
+ ] }),
2039
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2040
+ "button",
2041
+ {
2042
+ type: "button",
2043
+ onClick: () => setPhase("chat"),
2044
+ style: {
2045
+ alignSelf: "flex-start",
2046
+ border: "none",
2047
+ background: "transparent",
2048
+ color: t2.textMuted,
2049
+ fontSize: "12px",
2050
+ fontFamily: "inherit",
2051
+ padding: "9px 0",
2052
+ cursor: "pointer",
2053
+ textDecoration: "underline"
2054
+ },
2055
+ children: "Not quite \u2014 keep chatting"
2056
+ }
2057
+ )
2058
+ ]
2059
+ }
2060
+ ),
2061
+ phase === "solved" && solved && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
2062
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: "8px" }, children: [
2063
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Avatar, { who: "assistant", theme: t2 }),
2064
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2065
+ "div",
2066
+ {
2067
+ style: {
2068
+ padding: "9px 12px",
2069
+ borderRadius: "12px 12px 12px 4px",
2070
+ backgroundColor: t2.bgSecondary,
2071
+ fontSize: "13px",
2072
+ lineHeight: 1.55,
2073
+ maxWidth: "88%",
2074
+ whiteSpace: "pre-wrap"
2075
+ },
2076
+ children: solved
2077
+ }
2078
+ )
2079
+ ] }),
2080
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2081
+ "span",
2082
+ {
2083
+ style: { fontSize: "11.5px", color: t2.textMuted, paddingLeft: "32px" },
2084
+ children: "Nothing was filed \u2014 you are all set."
2085
+ }
2086
+ )
2087
+ ] }),
2088
+ submitted && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
2089
+ "div",
2090
+ {
2091
+ style: {
2092
+ textAlign: "center",
2093
+ padding: "24px 0",
2094
+ color: t2.accent,
2095
+ fontSize: "14px",
2096
+ fontWeight: 600
2097
+ },
2098
+ children: [
2099
+ reportTypeLabel,
2100
+ " sent. Thank you!"
2101
+ ]
2102
+ }
2103
+ )
2104
+ ]
2105
+ }
2106
+ )
2107
+ }
2108
+ ),
2109
+ !submitted && phase !== "type" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2110
+ "div",
2111
+ {
2112
+ style: {
2113
+ flexShrink: 0,
2114
+ borderTop: `1px solid ${t2.border}`,
2115
+ padding: "12px 16px",
2116
+ paddingBottom: narrow ? "max(12px, env(safe-area-inset-bottom))" : "12px",
2117
+ backgroundColor: t2.bg
2118
+ },
2119
+ children: phase === "solved" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2120
+ "button",
2121
+ {
2122
+ type: "button",
2123
+ "data-gg-sheet-send": "",
2124
+ onClick: () => (onFinish != null ? onFinish : onClose)(),
2125
+ style: {
2126
+ width: "100%",
2127
+ padding: "12px",
2128
+ borderRadius: "10px",
2129
+ border: "none",
2130
+ backgroundColor: t2.accent,
2131
+ color: t2.accentText,
2132
+ fontSize: "14px",
2133
+ fontWeight: 700,
2134
+ fontFamily: "inherit",
2135
+ cursor: "pointer"
2136
+ },
2137
+ children: "Done"
2138
+ }
2139
+ ) : phase === "rating" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2140
+ "button",
2141
+ {
2142
+ type: "button",
2143
+ "data-gg-sheet-send": "",
2144
+ onClick: onSend,
2145
+ disabled: isSubmitting || rating < 1,
2146
+ style: {
2147
+ width: "100%",
2148
+ padding: "12px",
2149
+ borderRadius: "10px",
2150
+ border: "none",
2151
+ backgroundColor: isSubmitting || rating < 1 ? t2.bgSecondary : "#f59e0b",
2152
+ color: isSubmitting || rating < 1 ? t2.textMuted : "#1a1a1a",
2153
+ fontSize: "14px",
2154
+ fontWeight: 700,
2155
+ fontFamily: "inherit",
2156
+ cursor: isSubmitting || rating < 1 ? "default" : "pointer"
2157
+ },
2158
+ children: isSubmitting ? "Sending\u2026" : rating < 1 ? "Pick a star first" : "Send Rating"
2159
+ }
2160
+ ) : phase === "draft" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2161
+ "button",
2162
+ {
2163
+ type: "button",
2164
+ "data-gg-sheet-send": "",
2165
+ onClick: onSend,
2166
+ disabled: isSubmitting || !description.trim(),
2167
+ style: {
2168
+ width: "100%",
2169
+ padding: "12px",
2170
+ borderRadius: "10px",
2171
+ border: "none",
2172
+ backgroundColor: isSubmitting || !description.trim() ? t2.bgSecondary : t2.accent,
2173
+ color: isSubmitting || !description.trim() ? t2.textMuted : t2.accentText,
2174
+ fontSize: "14px",
2175
+ fontWeight: 700,
2176
+ fontFamily: "inherit",
2177
+ cursor: isSubmitting || !description.trim() ? "default" : "pointer"
2178
+ },
2179
+ children: isSubmitting ? "Sending\u2026" : duplicate ? `Add to #${duplicate.number}` : "Send Report"
2180
+ }
2181
+ ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: "8px", alignItems: "flex-end" }, children: [
2182
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2183
+ "textarea",
2184
+ {
2185
+ ref: inputRef,
2186
+ value: input,
2187
+ onChange: (e) => setInput(e.target.value),
2188
+ onKeyDown: (e) => {
2189
+ if (e.key === "Enter" && !e.shiftKey) {
2190
+ e.preventDefault();
2191
+ send(input);
2192
+ }
2193
+ },
2194
+ placeholder: "Type your answer\u2026",
2195
+ rows: 1,
2196
+ disabled: busy,
2197
+ autoFocus: true,
2198
+ style: {
2199
+ flex: 1,
2200
+ minHeight: "42px",
2201
+ maxHeight: "120px",
2202
+ padding: "11px 12px",
2203
+ borderRadius: "10px",
2204
+ border: `1px solid ${t2.inputBorder}`,
2205
+ backgroundColor: t2.inputBg,
2206
+ color: t2.text,
2207
+ fontSize: "13px",
2208
+ lineHeight: 1.4,
2209
+ fontFamily: "inherit",
2210
+ resize: "none",
2211
+ outline: "none",
2212
+ boxSizing: "border-box"
2213
+ }
2214
+ }
2215
+ ),
2216
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2217
+ "button",
2218
+ {
2219
+ type: "button",
2220
+ "data-gg-sheet-send": "",
2221
+ onClick: () => send(input),
2222
+ disabled: busy || !input.trim(),
2223
+ "aria-label": "Send message",
2224
+ style: {
2225
+ flexShrink: 0,
2226
+ width: "42px",
2227
+ height: "42px",
2228
+ borderRadius: "10px",
2229
+ border: "none",
2230
+ display: "inline-flex",
2231
+ alignItems: "center",
2232
+ justifyContent: "center",
2233
+ backgroundColor: busy || !input.trim() ? t2.bgSecondary : t2.accent,
2234
+ color: busy || !input.trim() ? t2.textMuted : t2.accentText,
2235
+ cursor: busy || !input.trim() ? "default" : "pointer"
2236
+ },
2237
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "17", height: "17", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2238
+ "path",
2239
+ {
2240
+ d: "M3 20.5L21.5 12 3 3.5V10l12 2-12 2v6.5z",
2241
+ fill: "currentColor"
2242
+ }
2243
+ ) })
2244
+ }
2245
+ )
2246
+ ] })
2247
+ }
2248
+ )
2249
+ ]
2250
+ }
2251
+ )
2252
+ }
2253
+ )
2254
+ ] }),
2255
+ document.body
1164
2256
  );
1165
2257
  }
1166
2258
  var GLITCHGRAB_SHORTCUT = "Ctrl+Shift+G";
@@ -1342,13 +2434,13 @@ function ReporterChip({
1342
2434
  const label = isAnonymous ? "Anonymous" : name;
1343
2435
  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 ");
1344
2436
  const showAvatarImage = !!avatarUrl && !avatarFailed;
1345
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
2437
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1346
2438
  "span",
1347
2439
  {
1348
2440
  title,
1349
2441
  style: { display: "flex", alignItems: "center", gap: "6px", minWidth: 0 },
1350
2442
  children: [
1351
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2443
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1352
2444
  "span",
1353
2445
  {
1354
2446
  "aria-hidden": "true",
@@ -1368,7 +2460,7 @@ function ReporterChip({
1368
2460
  color: isAnonymous ? t2.textMuted : t2.accentText,
1369
2461
  border: `1px solid ${isAnonymous ? t2.inputBorder : "transparent"}`
1370
2462
  },
1371
- children: showAvatarImage ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2463
+ children: showAvatarImage ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1372
2464
  "img",
1373
2465
  {
1374
2466
  src: avatarUrl,
@@ -1378,9 +2470,9 @@ function ReporterChip({
1378
2470
  onError: () => setAvatarFailed(true),
1379
2471
  style: { width: "100%", height: "100%", objectFit: "cover" }
1380
2472
  }
1381
- ) : initials ? initials : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { width: "10", height: "10", viewBox: "0 0 16 16", fill: "none", children: [
1382
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "8", cy: "5.5", r: "2.75", stroke: "currentColor", strokeWidth: "1.4" }),
1383
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2473
+ ) : initials ? initials : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { width: "10", height: "10", viewBox: "0 0 16 16", fill: "none", children: [
2474
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { cx: "8", cy: "5.5", r: "2.75", stroke: "currentColor", strokeWidth: "1.4" }),
2475
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1384
2476
  "path",
1385
2477
  {
1386
2478
  d: "M2.75 13.5c0-2.35 2.35-3.75 5.25-3.75s5.25 1.4 5.25 3.75",
@@ -1392,7 +2484,7 @@ function ReporterChip({
1392
2484
  ] })
1393
2485
  }
1394
2486
  ),
1395
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
2487
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1396
2488
  "span",
1397
2489
  {
1398
2490
  style: {
@@ -1506,6 +2598,8 @@ function ReportDialog({
1506
2598
  report,
1507
2599
  sendFeedback: sendFeedback2,
1508
2600
  enhanceText: enhanceText2,
2601
+ assist,
2602
+ assistContext = null,
1509
2603
  transcribeAudio: transcribeAudio2,
1510
2604
  types,
1511
2605
  showSeverity = true,
@@ -1514,7 +2608,13 @@ function ReportDialog({
1514
2608
  onClose,
1515
2609
  headerSlot
1516
2610
  }) {
2611
+ var _a, _b;
1517
2612
  const [isEnhancing, setIsEnhancing] = (0, import_react.useState)(false);
2613
+ const [assistOpen, setAssistOpen] = (0, import_react.useState)(false);
2614
+ const [assistNotice, setAssistNotice] = (0, import_react.useState)(null);
2615
+ const [assistUsed, setAssistUsed] = (0, import_react.useState)(false);
2616
+ const [typeChosen, setTypeChosen] = (0, import_react.useState)(false);
2617
+ const [duplicateIssueNumber, setDuplicateIssueNumber] = (0, import_react.useState)(null);
1518
2618
  const [isEnhanced, setIsEnhanced] = (0, import_react.useState)(false);
1519
2619
  const [originalDescription, setOriginalDescription] = (0, import_react.useState)(
1520
2620
  null
@@ -1622,6 +2722,7 @@ function ReportDialog({
1622
2722
  e.preventDefault();
1623
2723
  setRating(Number(e.key));
1624
2724
  setReportType("RATING");
2725
+ setTypeChosen(true);
1625
2726
  setStep(2);
1626
2727
  return;
1627
2728
  }
@@ -1633,6 +2734,7 @@ function ReportDialog({
1633
2734
  if (match) {
1634
2735
  e.preventDefault();
1635
2736
  setReportType(match);
2737
+ setTypeChosen(true);
1636
2738
  setStep(2);
1637
2739
  }
1638
2740
  };
@@ -1640,11 +2742,11 @@ function ReportDialog({
1640
2742
  return () => window.removeEventListener("keydown", onKey);
1641
2743
  }, [isOpen, step, sendFeedback2, availableTypes.join(",")]);
1642
2744
  const handleTileGridKeyDown = (e) => {
1643
- var _a, _b, _c;
2745
+ var _a2, _b2, _c;
1644
2746
  const keys = ["ArrowRight", "ArrowLeft", "ArrowDown", "ArrowUp"];
1645
2747
  if (!keys.includes(e.key)) return;
1646
2748
  const tiles = Array.from(
1647
- (_b = (_a = tileGridRef.current) == null ? void 0 : _a.querySelectorAll("button[data-gg-type]")) != null ? _b : []
2749
+ (_b2 = (_a2 = tileGridRef.current) == null ? void 0 : _a2.querySelectorAll("button[data-gg-type]")) != null ? _b2 : []
1648
2750
  );
1649
2751
  if (tiles.length === 0) return;
1650
2752
  e.preventDefault();
@@ -1686,10 +2788,12 @@ function ReportDialog({
1686
2788
  setAnnotatingIndex(null);
1687
2789
  if (availableTypes.length === 1) {
1688
2790
  setReportType(availableTypes[0]);
2791
+ setTypeChosen(true);
1689
2792
  setStep(2);
1690
2793
  }
1691
2794
  const shot = await captureScreenshot();
1692
2795
  if (shot) setScreenshots([shot]);
2796
+ if (assist && !assistUsed) setAssistOpen(true);
1693
2797
  setIsOpen(true);
1694
2798
  };
1695
2799
  (0, import_react.useEffect)(() => {
@@ -1699,6 +2803,7 @@ function ReportDialog({
1699
2803
  if (detail == null ? void 0 : detail.description) setDescription(detail.description);
1700
2804
  if (detail == null ? void 0 : detail.type) {
1701
2805
  setReportType(detail.type);
2806
+ setTypeChosen(true);
1702
2807
  setStep(2);
1703
2808
  }
1704
2809
  handleOpen();
@@ -1722,8 +2827,8 @@ function ReportDialog({
1722
2827
  (0, import_react.useEffect)(() => {
1723
2828
  if (previewIndex === null || annotatingIndex !== null) return;
1724
2829
  const handlePointerDown = (e) => {
1725
- var _a;
1726
- if (!((_a = previewImgRef.current) == null ? void 0 : _a.contains(e.target))) {
2830
+ var _a2;
2831
+ if (!((_a2 = previewImgRef.current) == null ? void 0 : _a2.contains(e.target))) {
1727
2832
  closePreview();
1728
2833
  }
1729
2834
  };
@@ -1731,17 +2836,17 @@ function ReportDialog({
1731
2836
  return () => document.removeEventListener("pointerdown", handlePointerDown, true);
1732
2837
  }, [previewIndex, annotatingIndex]);
1733
2838
  (0, import_react.useEffect)(() => {
1734
- var _a;
2839
+ var _a2;
1735
2840
  const el = previewScrollRef.current;
1736
2841
  if (!previewZoomed || !el) return;
1737
- const anchor = (_a = zoomAnchorRef.current) != null ? _a : { fx: 0.5, fy: 0.5 };
2842
+ const anchor = (_a2 = zoomAnchorRef.current) != null ? _a2 : { fx: 0.5, fy: 0.5 };
1738
2843
  el.scrollLeft = anchor.fx * el.scrollWidth - el.clientWidth / 2;
1739
2844
  el.scrollTop = anchor.fy * el.scrollHeight - el.clientHeight / 2;
1740
2845
  }, [previewZoomed]);
1741
2846
  const togglePreviewZoom = (e) => {
1742
- var _a;
2847
+ var _a2;
1743
2848
  e.stopPropagation();
1744
- if ((_a = panRef.current) == null ? void 0 : _a.moved) return;
2849
+ if ((_a2 = panRef.current) == null ? void 0 : _a2.moved) return;
1745
2850
  if (!previewZoomed && !canZoomPreview) return;
1746
2851
  const img = previewImgElRef.current;
1747
2852
  if (!previewZoomed && img) {
@@ -1776,9 +2881,9 @@ function ReportDialog({
1776
2881
  el.scrollTop = start.top - dy;
1777
2882
  };
1778
2883
  const handlePanEnd = (e) => {
1779
- var _a, _b;
2884
+ var _a2, _b2;
1780
2885
  const el = previewScrollRef.current;
1781
- const moved = (_b = (_a = panRef.current) == null ? void 0 : _a.moved) != null ? _b : false;
2886
+ const moved = (_b2 = (_a2 = panRef.current) == null ? void 0 : _a2.moved) != null ? _b2 : false;
1782
2887
  try {
1783
2888
  el == null ? void 0 : el.releasePointerCapture(e.pointerId);
1784
2889
  } catch (e2) {
@@ -1795,9 +2900,9 @@ function ReportDialog({
1795
2900
  (0, import_react.useEffect)(() => {
1796
2901
  if (!isOpen) return;
1797
2902
  const handlePaste = (e) => {
1798
- var _a;
2903
+ var _a2;
1799
2904
  try {
1800
- const items = (_a = e.clipboardData) == null ? void 0 : _a.items;
2905
+ const items = (_a2 = e.clipboardData) == null ? void 0 : _a2.items;
1801
2906
  if (!items) return;
1802
2907
  const pasted = [];
1803
2908
  for (let i = 0; i < items.length; i++) {
@@ -1823,16 +2928,16 @@ function ReportDialog({
1823
2928
  return () => clearInterval(id);
1824
2929
  }, [isOpen, transcribeAudio2]);
1825
2930
  const stopVoice = () => {
1826
- var _a, _b;
2931
+ var _a2, _b2;
1827
2932
  usingWebSpeechRef.current = false;
1828
- (_a = recognitionRef.current) == null ? void 0 : _a.stop();
2933
+ (_a2 = recognitionRef.current) == null ? void 0 : _a2.stop();
1829
2934
  recognitionRef.current = null;
1830
2935
  sarvamChunksRef.current = [];
1831
2936
  const stream = streamRef.current;
1832
2937
  streamRef.current = null;
1833
2938
  stream == null ? void 0 : stream.getTracks().forEach((t22) => t22.stop());
1834
2939
  try {
1835
- (_b = mediaRecorderRef.current) == null ? void 0 : _b.stop();
2940
+ (_b2 = mediaRecorderRef.current) == null ? void 0 : _b2.stop();
1836
2941
  } catch (e) {
1837
2942
  }
1838
2943
  mediaRecorderRef.current = null;
@@ -1840,16 +2945,28 @@ function ReportDialog({
1840
2945
  setIsTranscribing(false);
1841
2946
  };
1842
2947
  const stopListeningAndTranscribe = () => {
1843
- var _a, _b;
2948
+ var _a2, _b2;
1844
2949
  usingWebSpeechRef.current = false;
1845
- (_a = recognitionRef.current) == null ? void 0 : _a.stop();
2950
+ (_a2 = recognitionRef.current) == null ? void 0 : _a2.stop();
1846
2951
  recognitionRef.current = null;
1847
2952
  setIsListening(false);
1848
2953
  try {
1849
- (_b = mediaRecorderRef.current) == null ? void 0 : _b.stop();
2954
+ (_b2 = mediaRecorderRef.current) == null ? void 0 : _b2.stop();
1850
2955
  } catch (e) {
1851
2956
  }
1852
2957
  };
2958
+ const sheetUp = !!assist && assistOpen;
2959
+ (0, import_react.useEffect)(() => {
2960
+ const el = modalRef.current;
2961
+ if (!el) return;
2962
+ if (sheetUp) {
2963
+ el.setAttribute("inert", "");
2964
+ el.setAttribute("aria-hidden", "true");
2965
+ } else {
2966
+ el.removeAttribute("inert");
2967
+ el.removeAttribute("aria-hidden");
2968
+ }
2969
+ }, [sheetUp, isOpen]);
1853
2970
  const handleClose = () => {
1854
2971
  stopVoice();
1855
2972
  setIsOpen(false);
@@ -1860,11 +2977,16 @@ function ReportDialog({
1860
2977
  setRating(0);
1861
2978
  setHoveredStar(0);
1862
2979
  setReportType("BUG");
2980
+ setTypeChosen(false);
2981
+ setDuplicateIssueNumber(null);
1863
2982
  setSeverity("medium");
1864
2983
  setValidationError(null);
1865
2984
  setVoiceError(null);
1866
2985
  setIsEnhanced(false);
1867
2986
  setOriginalDescription(null);
2987
+ setAssistOpen(false);
2988
+ setAssistUsed(false);
2989
+ setAssistNotice(null);
1868
2990
  };
1869
2991
  const toggleVoice = async () => {
1870
2992
  if (isListening) {
@@ -1967,7 +3089,7 @@ function ReportDialog({
1967
3089
  }
1968
3090
  };
1969
3091
  const handleSpaceDown = (e) => {
1970
- var _a;
3092
+ var _a2;
1971
3093
  if (e.code !== "Space") return;
1972
3094
  if (isListening || isPushToTalkRef.current) {
1973
3095
  e.preventDefault();
@@ -1975,7 +3097,7 @@ function ReportDialog({
1975
3097
  }
1976
3098
  if (e.repeat || !transcribeAudio2 || isTranscribing || spaceTimerRef.current)
1977
3099
  return;
1978
- const pos = (_a = e.currentTarget.selectionStart) != null ? _a : description.length;
3100
+ const pos = (_a2 = e.currentTarget.selectionStart) != null ? _a2 : description.length;
1979
3101
  spaceTimerRef.current = setTimeout(() => {
1980
3102
  spaceTimerRef.current = null;
1981
3103
  isPushToTalkRef.current = true;
@@ -2041,6 +3163,9 @@ function ReportDialog({
2041
3163
  if (showSeverity && reportType === "BUG") {
2042
3164
  metadata.severity = severity;
2043
3165
  }
3166
+ if (duplicateIssueNumber) {
3167
+ metadata.duplicateIssueNumber = String(duplicateIssueNumber);
3168
+ }
2044
3169
  const result = await report(
2045
3170
  // The RATING branch returned above, so anything reaching here is a real
2046
3171
  // ReportType — the widened tile union can't leak into the report API.
@@ -2064,9 +3189,9 @@ function ReportDialog({
2064
3189
  }
2065
3190
  };
2066
3191
  if (!mounted) return null;
2067
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
3192
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
2068
3193
  isOpen && (0, import_react_dom.createPortal)(
2069
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("style", { children: `
3194
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("style", { children: `
2070
3195
  @keyframes gg-pulse{0%,100%{opacity:1}50%{opacity:0.35}}
2071
3196
  @keyframes gg-b1{0%,100%{height:3px}40%{height:13px}}
2072
3197
  @keyframes gg-b2{0%,100%{height:8px}50%{height:3px}}
@@ -2103,7 +3228,7 @@ function ReportDialog({
2103
3228
  document.body
2104
3229
  ),
2105
3230
  isOpen && (0, import_react_dom.createPortal)(
2106
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3231
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2107
3232
  "div",
2108
3233
  {
2109
3234
  "data-glitchgrab-layer": "",
@@ -2112,7 +3237,10 @@ function ReportDialog({
2112
3237
  inset: 0,
2113
3238
  zIndex: 2147483647,
2114
3239
  pointerEvents: "auto",
2115
- display: "flex",
3240
+ // Hidden, not unmounted, while the AI sheet is in charge — the
3241
+ // dialog's state IS the report, and unmounting would drop the
3242
+ // screenshots, attachments and step the reporter is on.
3243
+ display: sheetUp ? "none" : "flex",
2116
3244
  alignItems: "center",
2117
3245
  justifyContent: "center",
2118
3246
  backgroundColor: "rgba(0,0,0,0.5)",
@@ -2123,7 +3251,7 @@ function ReportDialog({
2123
3251
  },
2124
3252
  onPointerDown: (e) => e.stopPropagation(),
2125
3253
  onFocus: (e) => e.stopPropagation(),
2126
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
3254
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
2127
3255
  "div",
2128
3256
  {
2129
3257
  ref: modalRef,
@@ -2145,7 +3273,7 @@ function ReportDialog({
2145
3273
  isolation: "isolate"
2146
3274
  },
2147
3275
  children: [
2148
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
3276
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
2149
3277
  "div",
2150
3278
  {
2151
3279
  style: {
@@ -2154,7 +3282,7 @@ function ReportDialog({
2154
3282
  borderBottom: `1px solid ${t2.border}`
2155
3283
  },
2156
3284
  children: [
2157
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
3285
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
2158
3286
  "div",
2159
3287
  {
2160
3288
  style: {
@@ -2163,7 +3291,7 @@ function ReportDialog({
2163
3291
  alignItems: "center"
2164
3292
  },
2165
3293
  children: [
2166
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
3294
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
2167
3295
  "div",
2168
3296
  {
2169
3297
  style: {
@@ -2172,7 +3300,7 @@ function ReportDialog({
2172
3300
  gap: "8px"
2173
3301
  },
2174
3302
  children: [
2175
- step > 1 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3303
+ step > 1 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2176
3304
  "button",
2177
3305
  {
2178
3306
  type: "button",
@@ -2186,14 +3314,14 @@ function ReportDialog({
2186
3314
  alignItems: "center"
2187
3315
  },
2188
3316
  "aria-label": "Back",
2189
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3317
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2190
3318
  "svg",
2191
3319
  {
2192
3320
  width: "16",
2193
3321
  height: "16",
2194
3322
  viewBox: "0 0 16 16",
2195
3323
  fill: "none",
2196
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3324
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2197
3325
  "path",
2198
3326
  {
2199
3327
  d: "M10 3L5 8L10 13",
@@ -2207,7 +3335,7 @@ function ReportDialog({
2207
3335
  )
2208
3336
  }
2209
3337
  ),
2210
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3338
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2211
3339
  "span",
2212
3340
  {
2213
3341
  style: {
@@ -2221,7 +3349,7 @@ function ReportDialog({
2221
3349
  ]
2222
3350
  }
2223
3351
  ),
2224
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
3352
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
2225
3353
  "div",
2226
3354
  {
2227
3355
  style: {
@@ -2230,7 +3358,7 @@ function ReportDialog({
2230
3358
  gap: "8px"
2231
3359
  },
2232
3360
  children: [
2233
- step === 1 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3361
+ step === 1 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2234
3362
  "span",
2235
3363
  {
2236
3364
  title: "Press this anywhere to open Glitchgrab",
@@ -2248,7 +3376,7 @@ function ReportDialog({
2248
3376
  children: getShortcutLabel()
2249
3377
  }
2250
3378
  ),
2251
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3379
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2252
3380
  "button",
2253
3381
  {
2254
3382
  type: "button",
@@ -2263,7 +3391,7 @@ function ReportDialog({
2263
3391
  justifyContent: "center"
2264
3392
  },
2265
3393
  "aria-label": "Close",
2266
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3394
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2267
3395
  "svg",
2268
3396
  {
2269
3397
  width: "16",
@@ -2271,7 +3399,7 @@ function ReportDialog({
2271
3399
  viewBox: "0 0 16 16",
2272
3400
  fill: "none",
2273
3401
  style: { display: "block" },
2274
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3402
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2275
3403
  "path",
2276
3404
  {
2277
3405
  d: "M4 4L12 12M12 4L4 12",
@@ -2290,7 +3418,7 @@ function ReportDialog({
2290
3418
  ]
2291
3419
  }
2292
3420
  ),
2293
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3421
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2294
3422
  "div",
2295
3423
  {
2296
3424
  style: {
@@ -2300,12 +3428,12 @@ function ReportDialog({
2300
3428
  gap: "0",
2301
3429
  marginTop: "12px"
2302
3430
  },
2303
- children: [1, 2].map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
3431
+ children: [1, 2].map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
2304
3432
  "div",
2305
3433
  {
2306
3434
  style: { display: "flex", alignItems: "center" },
2307
3435
  children: [
2308
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3436
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2309
3437
  "div",
2310
3438
  {
2311
3439
  style: {
@@ -2317,7 +3445,7 @@ function ReportDialog({
2317
3445
  }
2318
3446
  }
2319
3447
  ),
2320
- i < 1 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3448
+ i < 1 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2321
3449
  "div",
2322
3450
  {
2323
3451
  style: {
@@ -2337,7 +3465,7 @@ function ReportDialog({
2337
3465
  ]
2338
3466
  }
2339
3467
  ),
2340
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3468
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2341
3469
  "div",
2342
3470
  {
2343
3471
  style: {
@@ -2346,7 +3474,7 @@ function ReportDialog({
2346
3474
  flex: "1 1 auto",
2347
3475
  minHeight: 0
2348
3476
  },
2349
- children: submitted ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
3477
+ children: submitted ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
2350
3478
  "div",
2351
3479
  {
2352
3480
  style: {
@@ -2361,9 +3489,9 @@ function ReportDialog({
2361
3489
  " sent. Thank you!"
2362
3490
  ]
2363
3491
  }
2364
- ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
2365
- step === 1 && headerSlot ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { marginBottom: "14px" }, children: headerSlot }) : null,
2366
- step === 1 && sendFeedback2 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
3492
+ ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
3493
+ step === 1 && headerSlot ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { marginBottom: "14px" }, children: headerSlot }) : null,
3494
+ step === 1 && sendFeedback2 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
2367
3495
  "div",
2368
3496
  {
2369
3497
  style: {
@@ -2380,16 +3508,16 @@ function ReportDialog({
2380
3508
  },
2381
3509
  onMouseLeave: () => setHoveredStar(0),
2382
3510
  children: [
2383
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3511
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2384
3512
  "span",
2385
3513
  {
2386
3514
  style: { fontSize: "13px", fontWeight: 600, color: t2.text },
2387
3515
  children: "How are we doing?"
2388
3516
  }
2389
3517
  ),
2390
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { display: "flex", gap: "4px" }, children: [1, 2, 3, 4, 5].map((star) => {
3518
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { display: "flex", gap: "4px" }, children: [1, 2, 3, 4, 5].map((star) => {
2391
3519
  const filled = star <= (hoveredStar || rating);
2392
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3520
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2393
3521
  "button",
2394
3522
  {
2395
3523
  type: "button",
@@ -2400,6 +3528,7 @@ function ReportDialog({
2400
3528
  onClick: () => {
2401
3529
  setRating(star);
2402
3530
  setReportType("RATING");
3531
+ setTypeChosen(true);
2403
3532
  setStep(2);
2404
3533
  },
2405
3534
  style: {
@@ -2409,7 +3538,7 @@ function ReportDialog({
2409
3538
  cursor: "pointer",
2410
3539
  lineHeight: 0
2411
3540
  },
2412
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "26", height: "26", viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3541
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { width: "26", height: "26", viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2413
3542
  "path",
2414
3543
  {
2415
3544
  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",
@@ -2426,7 +3555,7 @@ function ReportDialog({
2426
3555
  ]
2427
3556
  }
2428
3557
  ),
2429
- step === 1 && sendFeedback2 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
3558
+ step === 1 && sendFeedback2 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
2430
3559
  "div",
2431
3560
  {
2432
3561
  style: {
@@ -2436,13 +3565,13 @@ function ReportDialog({
2436
3565
  marginBottom: "16px"
2437
3566
  },
2438
3567
  children: [
2439
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { flex: 1, height: "1px", background: t2.border } }),
2440
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { fontSize: "11px", color: t2.textMuted }, children: "or report something" }),
2441
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { flex: 1, height: "1px", background: t2.border } })
3568
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { flex: 1, height: "1px", background: t2.border } }),
3569
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { fontSize: "11px", color: t2.textMuted }, children: "or report something" }),
3570
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { flex: 1, height: "1px", background: t2.border } })
2442
3571
  ]
2443
3572
  }
2444
3573
  ),
2445
- step === 1 && screenshots.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
3574
+ step === 1 && screenshots.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
2446
3575
  "div",
2447
3576
  {
2448
3577
  style: {
@@ -2456,7 +3585,7 @@ function ReportDialog({
2456
3585
  background: t2.inputBg
2457
3586
  },
2458
3587
  children: [
2459
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3588
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2460
3589
  "img",
2461
3590
  {
2462
3591
  src: screenshots[0],
@@ -2471,8 +3600,8 @@ function ReportDialog({
2471
3600
  }
2472
3601
  }
2473
3602
  ),
2474
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { fontSize: "11px", color: t2.textMuted, flex: 1 }, children: "Screenshot attached" }),
2475
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3603
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { fontSize: "11px", color: t2.textMuted, flex: 1 }, children: "Screenshot attached" }),
3604
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2476
3605
  "button",
2477
3606
  {
2478
3607
  type: "button",
@@ -2493,7 +3622,7 @@ function ReportDialog({
2493
3622
  ]
2494
3623
  }
2495
3624
  ),
2496
- step === 1 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3625
+ step === 1 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2497
3626
  "div",
2498
3627
  {
2499
3628
  ref: tileGridRef,
@@ -2503,13 +3632,14 @@ function ReportDialog({
2503
3632
  gridTemplateColumns: "1fr 1fr 1fr",
2504
3633
  gap: "10px"
2505
3634
  },
2506
- children: availableTypes.map((type) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
3635
+ children: availableTypes.map((type) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
2507
3636
  "button",
2508
3637
  {
2509
3638
  type: "button",
2510
3639
  "data-gg-type": type,
2511
3640
  onClick: () => {
2512
3641
  setReportType(type);
3642
+ setTypeChosen(true);
2513
3643
  setStep(2);
2514
3644
  },
2515
3645
  style: {
@@ -2533,7 +3663,7 @@ function ReportDialog({
2533
3663
  },
2534
3664
  children: [
2535
3665
  getTypeIcon(type, t2.accent, 22),
2536
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3666
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2537
3667
  "span",
2538
3668
  {
2539
3669
  style: {
@@ -2551,8 +3681,8 @@ function ReportDialog({
2551
3681
  ))
2552
3682
  }
2553
3683
  ),
2554
- step === 2 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
2555
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
3684
+ step === 2 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
3685
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
2556
3686
  "button",
2557
3687
  {
2558
3688
  type: "button",
@@ -2575,11 +3705,11 @@ function ReportDialog({
2575
3705
  children: [
2576
3706
  getTypeIcon(reportType, isRating ? "#f59e0b" : t2.accent, 13),
2577
3707
  getTypeLabel(reportType),
2578
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: t2.textMuted, fontWeight: 400 }, children: "\xB7 change" })
3708
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { color: t2.textMuted, fontWeight: 400 }, children: "\xB7 change" })
2579
3709
  ]
2580
3710
  }
2581
3711
  ),
2582
- isRating && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3712
+ isRating && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2583
3713
  "div",
2584
3714
  {
2585
3715
  style: {
@@ -2590,7 +3720,7 @@ function ReportDialog({
2590
3720
  onMouseLeave: () => setHoveredStar(0),
2591
3721
  children: [1, 2, 3, 4, 5].map((star) => {
2592
3722
  const filled = star <= (hoveredStar || rating);
2593
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3723
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2594
3724
  "button",
2595
3725
  {
2596
3726
  type: "button",
@@ -2607,7 +3737,7 @@ function ReportDialog({
2607
3737
  cursor: "pointer",
2608
3738
  lineHeight: 0
2609
3739
  },
2610
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "30", height: "30", viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3740
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { width: "30", height: "30", viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2611
3741
  "path",
2612
3742
  {
2613
3743
  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",
@@ -2623,8 +3753,48 @@ function ReportDialog({
2623
3753
  })
2624
3754
  }
2625
3755
  ),
2626
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { position: "relative" }, children: [
2627
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3756
+ assist && !isRating && !assistUsed && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3757
+ "button",
3758
+ {
3759
+ type: "button",
3760
+ onClick: () => {
3761
+ setAssistNotice(null);
3762
+ setTypeChosen(true);
3763
+ setAssistOpen(true);
3764
+ },
3765
+ style: {
3766
+ display: "inline-flex",
3767
+ alignItems: "center",
3768
+ gap: "6px",
3769
+ marginBottom: "10px",
3770
+ // 8px vertical keeps the tap target at ~32px.
3771
+ padding: "8px 10px",
3772
+ borderRadius: "6px",
3773
+ border: `1px solid ${t2.accent}`,
3774
+ background: "transparent",
3775
+ color: t2.accent,
3776
+ fontSize: "12px",
3777
+ fontWeight: 600,
3778
+ fontFamily: "inherit",
3779
+ cursor: "pointer"
3780
+ },
3781
+ title: "Answer a question or two and the assistant writes the report for you",
3782
+ children: [
3783
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3784
+ "path",
3785
+ {
3786
+ 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",
3787
+ stroke: t2.accent,
3788
+ strokeWidth: "1.5",
3789
+ strokeLinejoin: "round"
3790
+ }
3791
+ ) }),
3792
+ "Describe it with AI"
3793
+ ]
3794
+ }
3795
+ ),
3796
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { position: "relative" }, children: [
3797
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2628
3798
  "textarea",
2629
3799
  {
2630
3800
  ref: textareaRef,
@@ -2665,7 +3835,7 @@ function ReportDialog({
2665
3835
  autoFocus: true
2666
3836
  }
2667
3837
  ),
2668
- (isListening || isTranscribing) && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
3838
+ (isListening || isTranscribing) && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
2669
3839
  "span",
2670
3840
  {
2671
3841
  style: {
@@ -2683,7 +3853,7 @@ function ReportDialog({
2683
3853
  zIndex: 1
2684
3854
  },
2685
3855
  children: [
2686
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3856
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2687
3857
  "span",
2688
3858
  {
2689
3859
  style: {
@@ -2698,7 +3868,7 @@ function ReportDialog({
2698
3868
  }
2699
3869
  ),
2700
3870
  isTranscribing ? "Transcribing\u2026" : "REC",
2701
- isListening && !isTranscribing && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3871
+ isListening && !isTranscribing && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2702
3872
  "span",
2703
3873
  {
2704
3874
  style: {
@@ -2725,7 +3895,7 @@ function ReportDialog({
2725
3895
  dur: "0.55s",
2726
3896
  delay: "0.15s"
2727
3897
  }
2728
- ].map((b, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3898
+ ].map((b, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2729
3899
  "span",
2730
3900
  {
2731
3901
  style: {
@@ -2745,18 +3915,18 @@ function ReportDialog({
2745
3915
  ]
2746
3916
  }
2747
3917
  ),
2748
- enhanceText2 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
3918
+ enhanceText2 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
2749
3919
  "button",
2750
3920
  {
2751
3921
  type: "button",
2752
3922
  onClick: async () => {
2753
- var _a;
3923
+ var _a2;
2754
3924
  if (!description.trim() || isEnhancing) return;
2755
3925
  setIsEnhancing(true);
2756
3926
  try {
2757
3927
  const polished = await enhanceText2(
2758
3928
  description,
2759
- (_a = screenshots[0]) != null ? _a : null
3929
+ (_a2 = screenshots[0]) != null ? _a2 : null
2760
3930
  );
2761
3931
  if (polished && polished !== description) {
2762
3932
  setOriginalDescription(description);
@@ -2790,7 +3960,7 @@ function ReportDialog({
2790
3960
  },
2791
3961
  title: "Polish grammar \u2014 preserves your meaning",
2792
3962
  children: [
2793
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3963
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2794
3964
  "svg",
2795
3965
  {
2796
3966
  width: "11",
@@ -2798,7 +3968,7 @@ function ReportDialog({
2798
3968
  viewBox: "0 0 24 24",
2799
3969
  fill: "none",
2800
3970
  "aria-hidden": "true",
2801
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3971
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2802
3972
  "path",
2803
3973
  {
2804
3974
  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",
@@ -2813,7 +3983,7 @@ function ReportDialog({
2813
3983
  ]
2814
3984
  }
2815
3985
  ),
2816
- transcribeAudio2 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3986
+ transcribeAudio2 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2817
3987
  "button",
2818
3988
  {
2819
3989
  type: "button",
@@ -2839,7 +4009,7 @@ function ReportDialog({
2839
4009
  padding: 0,
2840
4010
  transition: "border-color 0.2s ease, color 0.2s ease"
2841
4011
  },
2842
- children: isListening ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4012
+ children: isListening ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2843
4013
  "svg",
2844
4014
  {
2845
4015
  width: "12",
@@ -2847,7 +4017,7 @@ function ReportDialog({
2847
4017
  viewBox: "0 0 24 24",
2848
4018
  fill: "currentColor",
2849
4019
  "aria-hidden": "true",
2850
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4020
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2851
4021
  "rect",
2852
4022
  {
2853
4023
  x: "6",
@@ -2858,7 +4028,7 @@ function ReportDialog({
2858
4028
  }
2859
4029
  )
2860
4030
  }
2861
- ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
4031
+ ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
2862
4032
  "svg",
2863
4033
  {
2864
4034
  width: "13",
@@ -2867,7 +4037,7 @@ function ReportDialog({
2867
4037
  fill: "none",
2868
4038
  "aria-hidden": "true",
2869
4039
  children: [
2870
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4040
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2871
4041
  "rect",
2872
4042
  {
2873
4043
  x: "9",
@@ -2879,7 +4049,7 @@ function ReportDialog({
2879
4049
  strokeWidth: "1.8"
2880
4050
  }
2881
4051
  ),
2882
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4052
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2883
4053
  "path",
2884
4054
  {
2885
4055
  d: "M5 10a7 7 0 0014 0M12 19v3M9 22h6",
@@ -2894,7 +4064,7 @@ function ReportDialog({
2894
4064
  }
2895
4065
  )
2896
4066
  ] }),
2897
- transcribeAudio2 && !isListening && !isTranscribing && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
4067
+ transcribeAudio2 && !isListening && !isTranscribing && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
2898
4068
  "div",
2899
4069
  {
2900
4070
  style: {
@@ -2908,16 +4078,16 @@ function ReportDialog({
2908
4078
  userSelect: "none"
2909
4079
  },
2910
4080
  children: [
2911
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { width: "11", height: "11", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2912
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z" }),
2913
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
2914
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "12", x2: "12", y1: "19", y2: "22" })
4081
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { width: "11", height: "11", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
4082
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z" }),
4083
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
4084
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "12", x2: "12", y1: "19", y2: "22" })
2915
4085
  ] }),
2916
4086
  "Hold Space to speak \u2014 we'll transcribe it"
2917
4087
  ]
2918
4088
  }
2919
4089
  ),
2920
- isEnhanced && originalDescription !== null && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
4090
+ isEnhanced && originalDescription !== null && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
2921
4091
  "div",
2922
4092
  {
2923
4093
  style: {
@@ -2931,7 +4101,7 @@ function ReportDialog({
2931
4101
  border: `1px solid ${t2.accent}40`
2932
4102
  },
2933
4103
  children: [
2934
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4104
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2935
4105
  "svg",
2936
4106
  {
2937
4107
  width: "12",
@@ -2939,7 +4109,7 @@ function ReportDialog({
2939
4109
  viewBox: "0 0 24 24",
2940
4110
  fill: "none",
2941
4111
  style: { flexShrink: 0 },
2942
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4112
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2943
4113
  "path",
2944
4114
  {
2945
4115
  d: "M12 3l1.5 4.5L18 9l-4.5 1.5L12 15l-1.5-4.5L6 9l4.5-1.5L12 3z",
@@ -2950,7 +4120,7 @@ function ReportDialog({
2950
4120
  )
2951
4121
  }
2952
4122
  ),
2953
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4123
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2954
4124
  "span",
2955
4125
  {
2956
4126
  style: {
@@ -2961,7 +4131,7 @@ function ReportDialog({
2961
4131
  children: "AI enhanced"
2962
4132
  }
2963
4133
  ),
2964
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4134
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2965
4135
  "button",
2966
4136
  {
2967
4137
  type: "button",
@@ -2983,7 +4153,7 @@ function ReportDialog({
2983
4153
  children: "Keep"
2984
4154
  }
2985
4155
  ),
2986
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4156
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2987
4157
  "button",
2988
4158
  {
2989
4159
  type: "button",
@@ -3009,7 +4179,7 @@ function ReportDialog({
3009
4179
  ]
3010
4180
  }
3011
4181
  ),
3012
- voiceError && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4182
+ voiceError && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3013
4183
  "p",
3014
4184
  {
3015
4185
  style: {
@@ -3021,8 +4191,21 @@ function ReportDialog({
3021
4191
  children: voiceError
3022
4192
  }
3023
4193
  ),
3024
- !isRating && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { marginTop: "10px" }, children: [
3025
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
4194
+ assistNotice && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4195
+ "p",
4196
+ {
4197
+ style: {
4198
+ color: t2.textMuted,
4199
+ fontSize: "12px",
4200
+ marginTop: "6px",
4201
+ marginBottom: 0,
4202
+ lineHeight: 1.5
4203
+ },
4204
+ children: assistNotice
4205
+ }
4206
+ ),
4207
+ !isRating && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { marginTop: "10px" }, children: [
4208
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3026
4209
  "span",
3027
4210
  {
3028
4211
  style: {
@@ -3038,7 +4221,7 @@ function ReportDialog({
3038
4221
  ]
3039
4222
  }
3040
4223
  ),
3041
- screenshots.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4224
+ screenshots.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3042
4225
  "div",
3043
4226
  {
3044
4227
  style: {
@@ -3047,7 +4230,7 @@ function ReportDialog({
3047
4230
  gap: "8px",
3048
4231
  marginBottom: "8px"
3049
4232
  },
3050
- children: screenshots.map((src, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
4233
+ children: screenshots.map((src, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3051
4234
  "div",
3052
4235
  {
3053
4236
  style: {
@@ -3056,7 +4239,7 @@ function ReportDialog({
3056
4239
  height: "56px"
3057
4240
  },
3058
4241
  children: [
3059
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4242
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3060
4243
  "img",
3061
4244
  {
3062
4245
  src,
@@ -3074,7 +4257,7 @@ function ReportDialog({
3074
4257
  }
3075
4258
  }
3076
4259
  ),
3077
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4260
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3078
4261
  "button",
3079
4262
  {
3080
4263
  type: "button",
@@ -3100,14 +4283,14 @@ function ReportDialog({
3100
4283
  alignItems: "center",
3101
4284
  justifyContent: "center"
3102
4285
  },
3103
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4286
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3104
4287
  "svg",
3105
4288
  {
3106
4289
  width: "8",
3107
4290
  height: "8",
3108
4291
  viewBox: "0 0 10 10",
3109
4292
  fill: "none",
3110
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4293
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3111
4294
  "path",
3112
4295
  {
3113
4296
  d: "M1 1L9 9M9 1L1 9",
@@ -3120,7 +4303,7 @@ function ReportDialog({
3120
4303
  )
3121
4304
  }
3122
4305
  ),
3123
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4306
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3124
4307
  "button",
3125
4308
  {
3126
4309
  type: "button",
@@ -3145,14 +4328,14 @@ function ReportDialog({
3145
4328
  justifyContent: "center",
3146
4329
  boxShadow: "0 2px 8px rgba(0,0,0,0.45)"
3147
4330
  },
3148
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4331
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3149
4332
  "svg",
3150
4333
  {
3151
4334
  width: "12",
3152
4335
  height: "12",
3153
4336
  viewBox: "0 0 24 24",
3154
4337
  fill: "none",
3155
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4338
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3156
4339
  "path",
3157
4340
  {
3158
4341
  d: "M12 20h9M16.5 3.5a2.12 2.12 0 013 3L7 19l-4 1 1-4L16.5 3.5z",
@@ -3172,7 +4355,7 @@ function ReportDialog({
3172
4355
  ))
3173
4356
  }
3174
4357
  ),
3175
- attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4358
+ attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3176
4359
  "div",
3177
4360
  {
3178
4361
  style: {
@@ -3181,7 +4364,7 @@ function ReportDialog({
3181
4364
  gap: "6px",
3182
4365
  marginBottom: "8px"
3183
4366
  },
3184
- children: attachments.map((a, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
4367
+ children: attachments.map((a, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3185
4368
  "div",
3186
4369
  {
3187
4370
  style: {
@@ -3193,7 +4376,7 @@ function ReportDialog({
3193
4376
  border: `1px solid ${t2.border}`
3194
4377
  },
3195
4378
  children: [
3196
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
4379
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3197
4380
  "svg",
3198
4381
  {
3199
4382
  width: "14",
@@ -3202,7 +4385,7 @@ function ReportDialog({
3202
4385
  fill: "none",
3203
4386
  style: { flexShrink: 0, opacity: 0.6 },
3204
4387
  children: [
3205
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4388
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3206
4389
  "path",
3207
4390
  {
3208
4391
  d: "M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z",
@@ -3212,7 +4395,7 @@ function ReportDialog({
3212
4395
  strokeLinejoin: "round"
3213
4396
  }
3214
4397
  ),
3215
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4398
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3216
4399
  "path",
3217
4400
  {
3218
4401
  d: "M14 2v6h6",
@@ -3225,7 +4408,7 @@ function ReportDialog({
3225
4408
  ]
3226
4409
  }
3227
4410
  ),
3228
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4411
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3229
4412
  "span",
3230
4413
  {
3231
4414
  style: {
@@ -3239,7 +4422,7 @@ function ReportDialog({
3239
4422
  children: a.name
3240
4423
  }
3241
4424
  ),
3242
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
4425
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3243
4426
  "span",
3244
4427
  {
3245
4428
  style: { fontSize: "10px", color: t2.textMuted },
@@ -3249,7 +4432,7 @@ function ReportDialog({
3249
4432
  ]
3250
4433
  }
3251
4434
  ),
3252
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4435
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3253
4436
  "button",
3254
4437
  {
3255
4438
  type: "button",
@@ -3273,14 +4456,14 @@ function ReportDialog({
3273
4456
  justifyContent: "center",
3274
4457
  flexShrink: 0
3275
4458
  },
3276
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4459
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3277
4460
  "svg",
3278
4461
  {
3279
4462
  width: "8",
3280
4463
  height: "8",
3281
4464
  viewBox: "0 0 10 10",
3282
4465
  fill: "none",
3283
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4466
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3284
4467
  "path",
3285
4468
  {
3286
4469
  d: "M1 1L9 9M9 1L1 9",
@@ -3299,12 +4482,12 @@ function ReportDialog({
3299
4482
  ))
3300
4483
  }
3301
4484
  ),
3302
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4485
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3303
4486
  "div",
3304
4487
  {
3305
4488
  onClick: () => {
3306
- var _a;
3307
- return (_a = fileInputRef.current) == null ? void 0 : _a.click();
4489
+ var _a2;
4490
+ return (_a2 = fileInputRef.current) == null ? void 0 : _a2.click();
3308
4491
  },
3309
4492
  onDrop: (e) => {
3310
4493
  e.preventDefault();
@@ -3325,7 +4508,7 @@ function ReportDialog({
3325
4508
  background: screenshotDragOver ? isDark ? "rgba(34,211,238,0.06)" : "rgba(8,145,178,0.04)" : "transparent",
3326
4509
  transition: "border-color 0.15s ease, background 0.15s ease"
3327
4510
  },
3328
- children: screenshots.length + attachments.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4511
+ children: screenshots.length + attachments.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3329
4512
  "p",
3330
4513
  {
3331
4514
  style: {
@@ -3336,8 +4519,8 @@ function ReportDialog({
3336
4519
  },
3337
4520
  children: screenshotDragOver ? "Drop to attach" : "+ Add more \xB7 Drag & drop \xB7 Paste"
3338
4521
  }
3339
- ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
3340
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
4522
+ ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
4523
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3341
4524
  "svg",
3342
4525
  {
3343
4526
  width: "22",
@@ -3350,7 +4533,7 @@ function ReportDialog({
3350
4533
  opacity: 0.45
3351
4534
  },
3352
4535
  children: [
3353
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4536
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3354
4537
  "rect",
3355
4538
  {
3356
4539
  x: "3",
@@ -3362,7 +4545,7 @@ function ReportDialog({
3362
4545
  strokeWidth: "1.5"
3363
4546
  }
3364
4547
  ),
3365
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4548
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3366
4549
  "circle",
3367
4550
  {
3368
4551
  cx: "8.5",
@@ -3372,7 +4555,7 @@ function ReportDialog({
3372
4555
  strokeWidth: "1.5"
3373
4556
  }
3374
4557
  ),
3375
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4558
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3376
4559
  "path",
3377
4560
  {
3378
4561
  d: "M21 15l-5-5L5 21",
@@ -3385,7 +4568,7 @@ function ReportDialog({
3385
4568
  ]
3386
4569
  }
3387
4570
  ),
3388
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4571
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3389
4572
  "p",
3390
4573
  {
3391
4574
  style: {
@@ -3397,7 +4580,7 @@ function ReportDialog({
3397
4580
  children: screenshotDragOver ? "Drop to attach" : "Add screenshots or files"
3398
4581
  }
3399
4582
  ),
3400
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4583
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3401
4584
  "p",
3402
4585
  {
3403
4586
  style: {
@@ -3412,8 +4595,8 @@ function ReportDialog({
3412
4595
  }
3413
4596
  )
3414
4597
  ] }),
3415
- showSeverity && reportType === "BUG" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { marginTop: "10px" }, children: [
3416
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4598
+ showSeverity && reportType === "BUG" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { marginTop: "10px" }, children: [
4599
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3417
4600
  "span",
3418
4601
  {
3419
4602
  style: {
@@ -3425,7 +4608,7 @@ function ReportDialog({
3425
4608
  children: "Severity"
3426
4609
  }
3427
4610
  ),
3428
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", gap: "6px" }, children: ["low", "medium", "high"].map((s) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4611
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { display: "flex", gap: "6px" }, children: ["low", "medium", "high"].map((s) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3429
4612
  "button",
3430
4613
  {
3431
4614
  type: "button",
@@ -3449,7 +4632,7 @@ function ReportDialog({
3449
4632
  s
3450
4633
  )) })
3451
4634
  ] }),
3452
- validationError && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4635
+ validationError && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3453
4636
  "p",
3454
4637
  {
3455
4638
  style: {
@@ -3460,7 +4643,7 @@ function ReportDialog({
3460
4643
  children: validationError
3461
4644
  }
3462
4645
  ),
3463
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4646
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3464
4647
  "button",
3465
4648
  {
3466
4649
  type: "button",
@@ -3487,7 +4670,7 @@ function ReportDialog({
3487
4670
  ] })
3488
4671
  }
3489
4672
  ),
3490
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
4673
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3491
4674
  "div",
3492
4675
  {
3493
4676
  style: {
@@ -3499,8 +4682,8 @@ function ReportDialog({
3499
4682
  gap: "12px"
3500
4683
  },
3501
4684
  children: [
3502
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ReporterChip, { reporter, t: t2 }),
3503
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4685
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ReporterChip, { reporter, t: t2 }),
4686
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3504
4687
  "span",
3505
4688
  {
3506
4689
  style: {
@@ -3522,7 +4705,7 @@ function ReportDialog({
3522
4705
  ),
3523
4706
  document.body
3524
4707
  ),
3525
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4708
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3526
4709
  "input",
3527
4710
  {
3528
4711
  ref: fileInputRef,
@@ -3534,7 +4717,7 @@ function ReportDialog({
3534
4717
  }
3535
4718
  ),
3536
4719
  isOpen && previewIndex !== null && screenshots[previewIndex] && (0, import_react_dom.createPortal)(
3537
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
4720
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3538
4721
  "div",
3539
4722
  {
3540
4723
  "data-glitchgrab-layer": "",
@@ -3556,7 +4739,7 @@ function ReportDialog({
3556
4739
  },
3557
4740
  onMouseDown: (e) => e.stopPropagation(),
3558
4741
  children: [
3559
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
4742
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3560
4743
  "div",
3561
4744
  {
3562
4745
  ref: previewImgRef,
@@ -3568,7 +4751,7 @@ function ReportDialog({
3568
4751
  },
3569
4752
  onClick: (e) => e.stopPropagation(),
3570
4753
  children: [
3571
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4754
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3572
4755
  "div",
3573
4756
  {
3574
4757
  ref: previewScrollRef,
@@ -3587,7 +4770,7 @@ function ReportDialog({
3587
4770
  touchAction: "none",
3588
4771
  cursor: "grab"
3589
4772
  } : { maxWidth: "100%", lineHeight: 0 },
3590
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4773
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3591
4774
  "img",
3592
4775
  {
3593
4776
  ref: previewImgElRef,
@@ -3615,7 +4798,7 @@ function ReportDialog({
3615
4798
  )
3616
4799
  }
3617
4800
  ),
3618
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
4801
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3619
4802
  "button",
3620
4803
  {
3621
4804
  type: "button",
@@ -3643,7 +4826,7 @@ function ReportDialog({
3643
4826
  animation: "gg-pulse 2s ease-in-out infinite"
3644
4827
  },
3645
4828
  children: [
3646
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4829
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3647
4830
  "path",
3648
4831
  {
3649
4832
  d: "M12 20h9M16.5 3.5a2.12 2.12 0 013 3L7 19l-4 1 1-4L16.5 3.5z",
@@ -3660,7 +4843,7 @@ function ReportDialog({
3660
4843
  ]
3661
4844
  }
3662
4845
  ),
3663
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4846
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3664
4847
  "div",
3665
4848
  {
3666
4849
  style: {
@@ -3669,7 +4852,7 @@ function ReportDialog({
3669
4852
  alignItems: "center",
3670
4853
  gap: "12px"
3671
4854
  },
3672
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4855
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3673
4856
  "span",
3674
4857
  {
3675
4858
  style: {
@@ -3691,7 +4874,7 @@ function ReportDialog({
3691
4874
  document.body
3692
4875
  ),
3693
4876
  isOpen && annotatingIndex !== null && screenshots[annotatingIndex] && (0, import_react_dom.createPortal)(
3694
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4877
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3695
4878
  AnnotationCanvas,
3696
4879
  {
3697
4880
  imageSrc: screenshots[annotatingIndex],
@@ -3705,29 +4888,70 @@ function ReportDialog({
3705
4888
  }
3706
4889
  ),
3707
4890
  document.body
4891
+ ),
4892
+ isOpen && sheetUp && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4893
+ AssistSheet,
4894
+ {
4895
+ assist,
4896
+ theme: {
4897
+ bg: t2.bg,
4898
+ bgSecondary: t2.bgSecondary,
4899
+ border: t2.border,
4900
+ text: t2.text,
4901
+ textMuted: t2.textMuted,
4902
+ inputBg: t2.inputBg,
4903
+ inputBorder: t2.inputBorder,
4904
+ accent: t2.accent,
4905
+ accentText: t2.accentText
4906
+ },
4907
+ screenshot: (_a = screenshots[0]) != null ? _a : null,
4908
+ attachmentCount: screenshots.length + attachments.length,
4909
+ context: { ...assistContext != null ? assistContext : {}, reportType },
4910
+ reportTypeLabel: getTypeLabel(reportType),
4911
+ typePicked: typeChosen,
4912
+ currentTile: reportType,
4913
+ tiles: sendFeedback2 ? [...availableTypes, "RATING"] : availableTypes,
4914
+ onPickType: (tile) => {
4915
+ setReportType(tile);
4916
+ setTypeChosen(true);
4917
+ setStep(2);
4918
+ },
4919
+ onDuplicateChange: setDuplicateIssueNumber,
4920
+ onFinish: handleClose,
4921
+ rating,
4922
+ onRatingChange: (value) => {
4923
+ setRating(value);
4924
+ if (validationError) setValidationError(null);
4925
+ },
4926
+ projectSlot: headerSlot,
4927
+ reporterName: (_b = reporter == null ? void 0 : reporter.name) != null ? _b : null,
4928
+ description,
4929
+ onDescriptionChange: (value) => {
4930
+ setDescription(value);
4931
+ if (validationError) setValidationError(null);
4932
+ },
4933
+ severity,
4934
+ onSeverityChange: setSeverity,
4935
+ showSeverity,
4936
+ isSubmitting,
4937
+ submitted,
4938
+ onSend: () => void handleSubmit(),
4939
+ onDegrade: (message) => {
4940
+ setAssistOpen(false);
4941
+ setAssistUsed(true);
4942
+ setAssistNotice(message);
4943
+ },
4944
+ onClose: () => {
4945
+ setAssistOpen(false);
4946
+ requestAnimationFrame(() => {
4947
+ var _a2;
4948
+ return (_a2 = textareaRef.current) == null ? void 0 : _a2.focus();
4949
+ });
4950
+ }
4951
+ }
3708
4952
  )
3709
4953
  ] });
3710
4954
  }
3711
- function getTypeLabel(type) {
3712
- switch (type) {
3713
- case "RATING":
3714
- return "Rating";
3715
- case "BUG":
3716
- return "Bug Report";
3717
- case "FEATURE_REQUEST":
3718
- return "Feature Request";
3719
- case "UI_IMPROVEMENT":
3720
- return "UI Improvement";
3721
- case "PERFORMANCE":
3722
- return "Performance";
3723
- case "SECURITY":
3724
- return "Security";
3725
- case "QUESTION":
3726
- return "Question";
3727
- case "OTHER":
3728
- return "Other";
3729
- }
3730
- }
3731
4955
  function getPlaceholder(type, idx = 0, hasVoice = false) {
3732
4956
  if (type === "RATING") return "What made it good \u2014 or what let you down? (optional)";
3733
4957
  if (hasVoice && idx === 1) return "Hold Space to speak \u2014 we'll transcribe it";
@@ -3758,7 +4982,7 @@ function getTypeIcon(type, color, size = 24) {
3758
4982
  };
3759
4983
  switch (type) {
3760
4984
  case "RATING":
3761
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4985
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3762
4986
  "path",
3763
4987
  {
3764
4988
  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",
@@ -3768,7 +4992,7 @@ function getTypeIcon(type, color, size = 24) {
3768
4992
  }
3769
4993
  ) });
3770
4994
  case "BUG":
3771
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4995
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3772
4996
  "path",
3773
4997
  {
3774
4998
  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",
@@ -3778,7 +5002,7 @@ function getTypeIcon(type, color, size = 24) {
3778
5002
  }
3779
5003
  ) });
3780
5004
  case "FEATURE_REQUEST":
3781
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5005
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3782
5006
  "path",
3783
5007
  {
3784
5008
  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",
@@ -3788,8 +5012,8 @@ function getTypeIcon(type, color, size = 24) {
3788
5012
  }
3789
5013
  ) });
3790
5014
  case "UI_IMPROVEMENT":
3791
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { ...props, children: [
3792
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5015
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { ...props, children: [
5016
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3793
5017
  "rect",
3794
5018
  {
3795
5019
  x: "3",
@@ -3801,7 +5025,7 @@ function getTypeIcon(type, color, size = 24) {
3801
5025
  strokeWidth: "1.5"
3802
5026
  }
3803
5027
  ),
3804
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5028
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3805
5029
  "path",
3806
5030
  {
3807
5031
  d: "M3 9h18M9 21V9",
@@ -3812,7 +5036,7 @@ function getTypeIcon(type, color, size = 24) {
3812
5036
  )
3813
5037
  ] });
3814
5038
  case "PERFORMANCE":
3815
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5039
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3816
5040
  "path",
3817
5041
  {
3818
5042
  d: "M12 21a9 9 0 100-18 9 9 0 000 18zM12 12l4-4M12 7v.01",
@@ -3823,7 +5047,7 @@ function getTypeIcon(type, color, size = 24) {
3823
5047
  }
3824
5048
  ) });
3825
5049
  case "SECURITY":
3826
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5050
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3827
5051
  "path",
3828
5052
  {
3829
5053
  d: "M12 3l7 3v5c0 4.5-3 8.5-7 10-4-1.5-7-5.5-7-10V6l7-3z",
@@ -3833,9 +5057,9 @@ function getTypeIcon(type, color, size = 24) {
3833
5057
  }
3834
5058
  ) });
3835
5059
  case "QUESTION":
3836
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { ...props, children: [
3837
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "12", cy: "12", r: "10", stroke: color, strokeWidth: "1.5" }),
3838
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5060
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { ...props, children: [
5061
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { cx: "12", cy: "12", r: "10", stroke: color, strokeWidth: "1.5" }),
5062
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3839
5063
  "path",
3840
5064
  {
3841
5065
  d: "M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3M12 17h.01",
@@ -3847,7 +5071,7 @@ function getTypeIcon(type, color, size = 24) {
3847
5071
  )
3848
5072
  ] });
3849
5073
  case "OTHER":
3850
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5074
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3851
5075
  "path",
3852
5076
  {
3853
5077
  d: "M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2v10z",
@@ -3860,8 +5084,8 @@ function getTypeIcon(type, color, size = 24) {
3860
5084
  }
3861
5085
 
3862
5086
  // src/booking-dialog.tsx
3863
- var import_react3 = require("react");
3864
- var import_jsx_runtime3 = require("react/jsx-runtime");
5087
+ var import_react4 = require("react");
5088
+ var import_jsx_runtime4 = require("react/jsx-runtime");
3865
5089
  var t = {
3866
5090
  bg: "#141414",
3867
5091
  surface: "#1c1c1c",
@@ -3898,28 +5122,28 @@ function BookingDialog({
3898
5122
  onClose
3899
5123
  }) {
3900
5124
  var _a;
3901
- const [step, setStep] = (0, import_react3.useState)("slots");
3902
- const [slots, setSlots] = (0, import_react3.useState)(null);
3903
- const [heading, setHeading] = (0, import_react3.useState)({
5125
+ const [step, setStep] = (0, import_react4.useState)("slots");
5126
+ const [slots, setSlots] = (0, import_react4.useState)(null);
5127
+ const [heading, setHeading] = (0, import_react4.useState)({
3904
5128
  title: "Book a demo",
3905
5129
  description: null
3906
5130
  });
3907
- const [whatsappUrl, setWhatsappUrl] = (0, import_react3.useState)(null);
3908
- const [selected, setSelected] = (0, import_react3.useState)(null);
3909
- const [name, setName] = (0, import_react3.useState)("");
3910
- const [email, setEmail] = (0, import_react3.useState)("");
3911
- const [phone, setPhone] = (0, import_react3.useState)("");
3912
- const [note, setNote] = (0, import_react3.useState)("");
3913
- const [code, setCode] = (0, import_react3.useState)("");
3914
- const [bookingId, setBookingId] = (0, import_react3.useState)(null);
3915
- const [meetUrl, setMeetUrl] = (0, import_react3.useState)(null);
3916
- const [busy, setBusy] = (0, import_react3.useState)(false);
3917
- const [error, setError] = (0, import_react3.useState)(null);
3918
- const headers = (0, import_react3.useMemo)(
5131
+ const [whatsappUrl, setWhatsappUrl] = (0, import_react4.useState)(null);
5132
+ const [selected, setSelected] = (0, import_react4.useState)(null);
5133
+ const [name, setName] = (0, import_react4.useState)("");
5134
+ const [email, setEmail] = (0, import_react4.useState)("");
5135
+ const [phone, setPhone] = (0, import_react4.useState)("");
5136
+ const [note, setNote] = (0, import_react4.useState)("");
5137
+ const [code, setCode] = (0, import_react4.useState)("");
5138
+ const [bookingId, setBookingId] = (0, import_react4.useState)(null);
5139
+ const [meetUrl, setMeetUrl] = (0, import_react4.useState)(null);
5140
+ const [busy, setBusy] = (0, import_react4.useState)(false);
5141
+ const [error, setError] = (0, import_react4.useState)(null);
5142
+ const headers = (0, import_react4.useMemo)(
3919
5143
  () => ({ Authorization: `Bearer ${token}`, "Content-Type": "application/json" }),
3920
5144
  [token]
3921
5145
  );
3922
- const loadSlots = (0, import_react3.useCallback)(async () => {
5146
+ const loadSlots = (0, import_react4.useCallback)(async () => {
3923
5147
  var _a2, _b, _c;
3924
5148
  setError(null);
3925
5149
  setSlots(null);
@@ -3944,7 +5168,7 @@ function BookingDialog({
3944
5168
  setSlots([]);
3945
5169
  }
3946
5170
  }, [baseUrl, headers]);
3947
- (0, import_react3.useEffect)(() => {
5171
+ (0, import_react4.useEffect)(() => {
3948
5172
  if (!open) return;
3949
5173
  setStep("slots");
3950
5174
  setSelected(null);
@@ -3953,7 +5177,7 @@ function BookingDialog({
3953
5177
  setError(null);
3954
5178
  void loadSlots();
3955
5179
  }, [open, loadSlots]);
3956
- (0, import_react3.useEffect)(() => {
5180
+ (0, import_react4.useEffect)(() => {
3957
5181
  if (!open) return;
3958
5182
  const onKey = (e) => {
3959
5183
  if (e.key === "Escape") onClose();
@@ -4023,7 +5247,7 @@ function BookingDialog({
4023
5247
  }
4024
5248
  }
4025
5249
  const canSubmitDetails = name.trim() && email.includes("@") && phone.replace(/\D/g, "").length >= 8;
4026
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5250
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4027
5251
  "div",
4028
5252
  {
4029
5253
  onClick: (e) => {
@@ -4040,7 +5264,7 @@ function BookingDialog({
4040
5264
  padding: 16,
4041
5265
  fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif"
4042
5266
  },
4043
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
5267
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
4044
5268
  "div",
4045
5269
  {
4046
5270
  role: "dialog",
@@ -4058,7 +5282,7 @@ function BookingDialog({
4058
5282
  overflow: "hidden"
4059
5283
  },
4060
5284
  children: [
4061
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
5285
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
4062
5286
  "div",
4063
5287
  {
4064
5288
  style: {
@@ -4070,11 +5294,11 @@ function BookingDialog({
4070
5294
  gap: 12
4071
5295
  },
4072
5296
  children: [
4073
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
4074
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { fontSize: 15, fontWeight: 600 }, children: heading.title }),
4075
- heading.description && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { fontSize: 12, color: t.muted, marginTop: 2 }, children: heading.description })
5297
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
5298
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { fontSize: 15, fontWeight: 600 }, children: heading.title }),
5299
+ heading.description && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { fontSize: 12, color: t.muted, marginTop: 2 }, children: heading.description })
4076
5300
  ] }),
4077
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5301
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4078
5302
  "button",
4079
5303
  {
4080
5304
  onClick: onClose,
@@ -4086,10 +5310,10 @@ function BookingDialog({
4086
5310
  ]
4087
5311
  }
4088
5312
  ),
4089
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { padding: 18, overflowY: "auto", flex: "1 1 auto" }, children: [
4090
- error && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { color: t.danger, fontSize: 12, marginBottom: 12, lineHeight: 1.5 }, children: error }),
4091
- step === "slots" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
4092
- whatsappUrl && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
5313
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { padding: 18, overflowY: "auto", flex: "1 1 auto" }, children: [
5314
+ error && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { color: t.danger, fontSize: 12, marginBottom: 12, lineHeight: 1.5 }, children: error }),
5315
+ step === "slots" && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
5316
+ whatsappUrl && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
4093
5317
  "a",
4094
5318
  {
4095
5319
  href: whatsappUrl,
@@ -4108,15 +5332,15 @@ function BookingDialog({
4108
5332
  },
4109
5333
  children: [
4110
5334
  "\u{1F4AC} Rather book on WhatsApp?",
4111
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { display: "block", fontSize: 11, color: t.muted, marginTop: 2 }, children: "We'll ask the same questions in chat." })
5335
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { display: "block", fontSize: 11, color: t.muted, marginTop: 2 }, children: "We'll ask the same questions in chat." })
4112
5336
  ]
4113
5337
  }
4114
5338
  ),
4115
- slots === null && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { color: t.muted, fontSize: 13 }, children: "Finding times\u2026" }),
4116
- (slots == null ? void 0 : slots.length) === 0 && !error && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { color: t.muted, fontSize: 13 }, children: "No times available right now." }),
4117
- [...byDay.entries()].map(([day, daySlots]) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { marginBottom: 18 }, children: [
4118
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { fontSize: 11, color: t.muted, marginBottom: 8, textTransform: "uppercase", letterSpacing: ".6px" }, children: formatDay(daySlots[0].startsAt) }),
4119
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { display: "flex", flexWrap: "wrap", gap: 8 }, children: daySlots.map((slot) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5339
+ slots === null && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { color: t.muted, fontSize: 13 }, children: "Finding times\u2026" }),
5340
+ (slots == null ? void 0 : slots.length) === 0 && !error && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { color: t.muted, fontSize: 13 }, children: "No times available right now." }),
5341
+ [...byDay.entries()].map(([day, daySlots]) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { marginBottom: 18 }, children: [
5342
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { fontSize: 11, color: t.muted, marginBottom: 8, textTransform: "uppercase", letterSpacing: ".6px" }, children: formatDay(daySlots[0].startsAt) }),
5343
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { display: "flex", flexWrap: "wrap", gap: 8 }, children: daySlots.map((slot) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4120
5344
  "button",
4121
5345
  {
4122
5346
  onClick: () => {
@@ -4138,13 +5362,13 @@ function BookingDialog({
4138
5362
  )) })
4139
5363
  ] }, day))
4140
5364
  ] }),
4141
- step === "details" && selected && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: [
4142
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { fontSize: 13, color: t.muted }, children: [
5365
+ step === "details" && selected && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: [
5366
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { fontSize: 13, color: t.muted }, children: [
4143
5367
  formatDay(selected.startsAt),
4144
5368
  " \xB7 ",
4145
5369
  formatTime(selected.startsAt),
4146
5370
  " \xB7 ",
4147
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5371
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4148
5372
  "button",
4149
5373
  {
4150
5374
  onClick: () => setStep("slots"),
@@ -4153,9 +5377,9 @@ function BookingDialog({
4153
5377
  }
4154
5378
  )
4155
5379
  ] }),
4156
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Field, { label: "Your name", value: name, onChange: setName }),
4157
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Field, { label: "Email", value: email, onChange: setEmail, type: "email" }),
4158
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5380
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Field, { label: "Your name", value: name, onChange: setName }),
5381
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Field, { label: "Email", value: email, onChange: setEmail, type: "email" }),
5382
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4159
5383
  Field,
4160
5384
  {
4161
5385
  label: "Mobile number",
@@ -4165,8 +5389,8 @@ function BookingDialog({
4165
5389
  hint: "We send a code here to confirm, then a reminder before the call."
4166
5390
  }
4167
5391
  ),
4168
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Field, { label: "Anything we should know? (optional)", value: note, onChange: setNote }),
4169
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5392
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Field, { label: "Anything we should know? (optional)", value: note, onChange: setNote }),
5393
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4170
5394
  "button",
4171
5395
  {
4172
5396
  onClick: startBooking,
@@ -4176,10 +5400,10 @@ function BookingDialog({
4176
5400
  }
4177
5401
  )
4178
5402
  ] }),
4179
- step === "code" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: [
4180
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("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." }),
4181
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Field, { label: "Code", value: code, onChange: setCode }),
4182
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5403
+ step === "code" && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: [
5404
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("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." }),
5405
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Field, { label: "Code", value: code, onChange: setCode }),
5406
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4183
5407
  "button",
4184
5408
  {
4185
5409
  onClick: confirmBooking,
@@ -4189,15 +5413,15 @@ function BookingDialog({
4189
5413
  }
4190
5414
  )
4191
5415
  ] }),
4192
- step === "done" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: [
4193
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { fontSize: 15, fontWeight: 600 }, children: "You're booked." }),
4194
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { fontSize: 13, color: t.muted, lineHeight: 1.6 }, children: [
5416
+ step === "done" && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: [
5417
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { fontSize: 15, fontWeight: 600 }, children: "You're booked." }),
5418
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { fontSize: 13, color: t.muted, lineHeight: 1.6 }, children: [
4195
5419
  selected && `${formatDay(selected.startsAt)} at ${formatTime(selected.startsAt)}. `,
4196
5420
  "A calendar invite is on its way to ",
4197
5421
  email,
4198
5422
  ", and we'll send a WhatsApp reminder before the call."
4199
5423
  ] }),
4200
- meetUrl && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("a", { href: meetUrl, target: "_blank", rel: "noreferrer", style: { ...primaryStyle(false), textAlign: "center", textDecoration: "none" }, children: "Open the meeting link" })
5424
+ meetUrl && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("a", { href: meetUrl, target: "_blank", rel: "noreferrer", style: { ...primaryStyle(false), textAlign: "center", textDecoration: "none" }, children: "Open the meeting link" })
4201
5425
  ] })
4202
5426
  ] })
4203
5427
  ]
@@ -4226,9 +5450,9 @@ function Field({
4226
5450
  type = "text",
4227
5451
  hint
4228
5452
  }) {
4229
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { style: { display: "block", fontSize: 11, color: t.muted }, children: [
5453
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { style: { display: "block", fontSize: 11, color: t.muted }, children: [
4230
5454
  label,
4231
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
5455
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4232
5456
  "input",
4233
5457
  {
4234
5458
  type,
@@ -4249,7 +5473,7 @@ function Field({
4249
5473
  }
4250
5474
  }
4251
5475
  ),
4252
- hint && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { marginTop: 4, fontSize: 10, color: t.muted }, children: hint })
5476
+ hint && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { marginTop: 4, fontSize: 10, color: t.muted }, children: hint })
4253
5477
  ] });
4254
5478
  }
4255
5479
 
@@ -4390,11 +5614,11 @@ function matchesShortcut(e) {
4390
5614
  }
4391
5615
 
4392
5616
  // src/provider.tsx
4393
- var import_jsx_runtime4 = require("react/jsx-runtime");
5617
+ var import_jsx_runtime5 = require("react/jsx-runtime");
4394
5618
  var DEFAULT_BASE_URL2 = "https://glitchgrab.dev";
4395
- var GlitchgrabContext = (0, import_react4.createContext)(null);
5619
+ var GlitchgrabContext = (0, import_react5.createContext)(null);
4396
5620
  function useGlitchgrab() {
4397
- const ctx = (0, import_react4.useContext)(GlitchgrabContext);
5621
+ const ctx = (0, import_react5.useContext)(GlitchgrabContext);
4398
5622
  if (!ctx) {
4399
5623
  throw new Error("useGlitchgrab must be used within a GlitchgrabProvider");
4400
5624
  }
@@ -4417,7 +5641,7 @@ function GlitchgrabProviderInner({
4417
5641
  context: appContext2,
4418
5642
  responseBodyOrigins: responseBodyOrigins2
4419
5643
  }) {
4420
- const visitedPagesRef = (0, import_react4.useRef)([]);
5644
+ const visitedPagesRef = (0, import_react5.useRef)([]);
4421
5645
  setRelease(release2);
4422
5646
  if (appContext2) setContexts(appContext2);
4423
5647
  registerCaptureConfig({
@@ -4429,12 +5653,12 @@ function GlitchgrabProviderInner({
4429
5653
  onError,
4430
5654
  onReportSent
4431
5655
  });
4432
- (0, import_react4.useEffect)(() => {
5656
+ (0, import_react5.useEffect)(() => {
4433
5657
  if (enableBreadcrumbs) {
4434
5658
  initBreadcrumbs(maxBreadcrumbs2, { responseBodyOrigins: responseBodyOrigins2 });
4435
5659
  }
4436
5660
  }, [enableBreadcrumbs, maxBreadcrumbs2, responseBodyOrigins2 == null ? void 0 : responseBodyOrigins2.join(",")]);
4437
- (0, import_react4.useEffect)(() => {
5661
+ (0, import_react5.useEffect)(() => {
4438
5662
  try {
4439
5663
  if (typeof window === "undefined") return;
4440
5664
  const trackPage = () => {
@@ -4471,7 +5695,7 @@ function GlitchgrabProviderInner({
4471
5695
  } catch (e) {
4472
5696
  }
4473
5697
  }, []);
4474
- (0, import_react4.useEffect)(() => {
5698
+ (0, import_react5.useEffect)(() => {
4475
5699
  try {
4476
5700
  if (typeof window === "undefined") return;
4477
5701
  if (process.env.NODE_ENV === "development") return;
@@ -4598,7 +5822,7 @@ function GlitchgrabProviderInner({
4598
5822
  } catch (e) {
4599
5823
  }
4600
5824
  }, [token, baseUrl, onError, onReportSent, session, ignoreErrors]);
4601
- const report = (0, import_react4.useCallback)(
5825
+ const report = (0, import_react5.useCallback)(
4602
5826
  async (type, description, metadata) => {
4603
5827
  var _a;
4604
5828
  try {
@@ -4632,11 +5856,11 @@ function GlitchgrabProviderInner({
4632
5856
  },
4633
5857
  [token, baseUrl, onReportSent, session]
4634
5858
  );
4635
- const reportBug = (0, import_react4.useCallback)(
5859
+ const reportBug = (0, import_react5.useCallback)(
4636
5860
  (description, metadata) => report("BUG", description, metadata),
4637
5861
  [report]
4638
5862
  );
4639
- const feedback = (0, import_react4.useCallback)(
5863
+ const feedback = (0, import_react5.useCallback)(
4640
5864
  async (rating, message, metadata) => {
4641
5865
  try {
4642
5866
  const context = captureContext(visitedPagesRef.current);
@@ -4664,32 +5888,32 @@ function GlitchgrabProviderInner({
4664
5888
  },
4665
5889
  [token, baseUrl, session]
4666
5890
  );
4667
- const openFeedbackDialog = (0, import_react4.useCallback)(() => {
5891
+ const openFeedbackDialog = (0, import_react5.useCallback)(() => {
4668
5892
  if (typeof window !== "undefined") {
4669
5893
  window.dispatchEvent(
4670
5894
  new CustomEvent("glitchgrab:open-report", { detail: { type: "RATING" } })
4671
5895
  );
4672
5896
  }
4673
5897
  }, []);
4674
- const captureError2 = (0, import_react4.useCallback)(
5898
+ const captureError2 = (0, import_react5.useCallback)(
4675
5899
  (error, options) => {
4676
5900
  captureError(error, options);
4677
5901
  },
4678
5902
  []
4679
5903
  );
4680
- const setContext2 = (0, import_react4.useCallback)((key, value) => {
5904
+ const setContext2 = (0, import_react5.useCallback)((key, value) => {
4681
5905
  setContext(key, value);
4682
5906
  }, []);
4683
- const setContexts2 = (0, import_react4.useCallback)((values) => {
5907
+ const setContexts2 = (0, import_react5.useCallback)((values) => {
4684
5908
  setContexts(values);
4685
5909
  }, []);
4686
- const addBreadcrumb2 = (0, import_react4.useCallback)(
5910
+ const addBreadcrumb2 = (0, import_react5.useCallback)(
4687
5911
  (message, data) => {
4688
5912
  addBreadcrumb("custom", message, data);
4689
5913
  },
4690
5914
  []
4691
5915
  );
4692
- const enhance = (0, import_react4.useCallback)(
5916
+ const enhance = (0, import_react5.useCallback)(
4693
5917
  async (text, screenshot) => {
4694
5918
  try {
4695
5919
  const ctx = captureContext(visitedPagesRef.current);
@@ -4705,7 +5929,27 @@ function GlitchgrabProviderInner({
4705
5929
  },
4706
5930
  [token, baseUrl]
4707
5931
  );
4708
- const transcribe = (0, import_react4.useCallback)(
5932
+ const assist = (0, import_react5.useCallback)(
5933
+ async (params) => {
5934
+ var _a;
5935
+ const ctx = captureContext(visitedPagesRef.current);
5936
+ return assistTurn(
5937
+ {
5938
+ ...params,
5939
+ context: {
5940
+ ...(_a = params.context) != null ? _a : {},
5941
+ url: ctx.url,
5942
+ visitedPages: ctx.visitedPages.slice(-5),
5943
+ breadcrumbs: ctx.breadcrumbs.slice(-25).map((b) => ({ type: b.type, message: b.message }))
5944
+ }
5945
+ },
5946
+ token,
5947
+ baseUrl
5948
+ );
5949
+ },
5950
+ [token, baseUrl]
5951
+ );
5952
+ const transcribe = (0, import_react5.useCallback)(
4709
5953
  async (blob) => {
4710
5954
  try {
4711
5955
  return await transcribeAudio(blob, token, baseUrl);
@@ -4715,12 +5959,12 @@ function GlitchgrabProviderInner({
4715
5959
  },
4716
5960
  [token, baseUrl]
4717
5961
  );
4718
- const openReportDialog = (0, import_react4.useCallback)((options) => {
5962
+ const openReportDialog = (0, import_react5.useCallback)((options) => {
4719
5963
  if (typeof window !== "undefined") {
4720
5964
  window.dispatchEvent(new CustomEvent("glitchgrab:open-report", { detail: options }));
4721
5965
  }
4722
5966
  }, []);
4723
- (0, import_react4.useEffect)(() => {
5967
+ (0, import_react5.useEffect)(() => {
4724
5968
  try {
4725
5969
  if (typeof document === "undefined") return;
4726
5970
  document.documentElement.setAttribute("data-glitchgrab-sdk", "1");
@@ -4728,10 +5972,11 @@ function GlitchgrabProviderInner({
4728
5972
  } catch (e) {
4729
5973
  }
4730
5974
  }, []);
4731
- const [projectName, setProjectName] = (0, import_react4.useState)(null);
4732
- const [bookingOpen, setBookingOpen] = (0, import_react4.useState)(false);
4733
- const openBookingDialog = (0, import_react4.useCallback)(() => setBookingOpen(true), []);
4734
- (0, import_react4.useEffect)(() => {
5975
+ const [projectName, setProjectName] = (0, import_react5.useState)(null);
5976
+ const [aiAssist, setAiAssist] = (0, import_react5.useState)(false);
5977
+ const [bookingOpen, setBookingOpen] = (0, import_react5.useState)(false);
5978
+ const openBookingDialog = (0, import_react5.useCallback)(() => setBookingOpen(true), []);
5979
+ (0, import_react5.useEffect)(() => {
4735
5980
  let cancelled = false;
4736
5981
  fetch(`${baseUrl}/api/v1/sdk/project`, {
4737
5982
  headers: { Authorization: `Bearer ${token}` }
@@ -4739,13 +5984,14 @@ function GlitchgrabProviderInner({
4739
5984
  var _a;
4740
5985
  if (cancelled || !(json == null ? void 0 : json.success) || !((_a = json.data) == null ? void 0 : _a.name)) return;
4741
5986
  setProjectName(json.data.name);
5987
+ setAiAssist(json.data.aiAssist === true);
4742
5988
  }).catch(() => {
4743
5989
  });
4744
5990
  return () => {
4745
5991
  cancelled = true;
4746
5992
  };
4747
5993
  }, [baseUrl, token]);
4748
- (0, import_react4.useEffect)(() => {
5994
+ (0, import_react5.useEffect)(() => {
4749
5995
  try {
4750
5996
  if (typeof window === "undefined") return;
4751
5997
  const handleKeyDown = (e) => {
@@ -4759,7 +6005,7 @@ function GlitchgrabProviderInner({
4759
6005
  } catch (e) {
4760
6006
  }
4761
6007
  }, [openReportDialog]);
4762
- const reporter = (0, import_react4.useMemo)(() => {
6008
+ const reporter = (0, import_react5.useMemo)(() => {
4763
6009
  var _a;
4764
6010
  if (!session) return null;
4765
6011
  const avatar = (_a = session.avatarUrl) != null ? _a : session.image;
@@ -4769,11 +6015,11 @@ function GlitchgrabProviderInner({
4769
6015
  avatarUrl: typeof avatar === "string" ? avatar : null
4770
6016
  };
4771
6017
  }, [session]);
4772
- const [shortcutLabel, setShortcutLabel] = (0, import_react4.useState)(GLITCHGRAB_SHORTCUT2);
4773
- (0, import_react4.useEffect)(() => {
6018
+ const [shortcutLabel, setShortcutLabel] = (0, import_react5.useState)(GLITCHGRAB_SHORTCUT2);
6019
+ (0, import_react5.useEffect)(() => {
4774
6020
  setShortcutLabel(getShortcutLabel2());
4775
6021
  }, []);
4776
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
6022
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
4777
6023
  GlitchgrabContext.Provider,
4778
6024
  {
4779
6025
  value: {
@@ -4793,7 +6039,7 @@ function GlitchgrabProviderInner({
4793
6039
  shortcutLabel
4794
6040
  },
4795
6041
  children: [
4796
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
6042
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4797
6043
  GlitchgrabErrorBoundary,
4798
6044
  {
4799
6045
  token,
@@ -4805,7 +6051,7 @@ function GlitchgrabProviderInner({
4805
6051
  children
4806
6052
  }
4807
6053
  ),
4808
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
6054
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4809
6055
  BookingDialog,
4810
6056
  {
4811
6057
  token,
@@ -4814,19 +6060,20 @@ function GlitchgrabProviderInner({
4814
6060
  onClose: () => setBookingOpen(false)
4815
6061
  }
4816
6062
  ),
4817
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
6063
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4818
6064
  ReportDialog,
4819
6065
  {
4820
6066
  report,
4821
6067
  sendFeedback: feedback,
4822
6068
  enhanceText: enhance,
6069
+ assist: aiAssist ? assist : void 0,
4823
6070
  transcribeAudio: transcribe,
4824
6071
  types,
4825
6072
  showSeverity,
4826
6073
  reporter,
4827
- headerSlot: projectName ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { fontSize: 11, color: "#9aa0a6" }, children: [
6074
+ headerSlot: projectName ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { fontSize: 11, color: "#9aa0a6" }, children: [
4828
6075
  "Reporting to ",
4829
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("strong", { style: { color: "#e5e5e5" }, children: projectName })
6076
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { style: { color: "#e5e5e5" }, children: projectName })
4830
6077
  ] }) : null
4831
6078
  }
4832
6079
  )
@@ -4835,21 +6082,21 @@ function GlitchgrabProviderInner({
4835
6082
  );
4836
6083
  }
4837
6084
  function GlitchgrabProvider(props) {
4838
- if (!props.token) return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children: props.children });
6085
+ if (!props.token) return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children: props.children });
4839
6086
  const resolvedProps = {
4840
6087
  ...props,
4841
6088
  baseUrl: props.baseUrl || DEFAULT_BASE_URL2
4842
6089
  };
4843
6090
  try {
4844
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(GlitchgrabProviderInner, { ...resolvedProps });
6091
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(GlitchgrabProviderInner, { ...resolvedProps });
4845
6092
  } catch (e) {
4846
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children: props.children });
6093
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children: props.children });
4847
6094
  }
4848
6095
  }
4849
6096
 
4850
6097
  // src/report-button.tsx
4851
- var import_react5 = require("react");
4852
- var import_jsx_runtime5 = require("react/jsx-runtime");
6098
+ var import_react6 = require("react");
6099
+ var import_jsx_runtime6 = require("react/jsx-runtime");
4853
6100
  function useGlitchgrabSafe() {
4854
6101
  try {
4855
6102
  return useGlitchgrab();
@@ -4864,7 +6111,7 @@ function ReportButton({
4864
6111
  children
4865
6112
  }) {
4866
6113
  var _a, _b;
4867
- const [capturing, setCapturing] = (0, import_react5.useState)(false);
6114
+ const [capturing, setCapturing] = (0, import_react6.useState)(false);
4868
6115
  const glitchgrab = useGlitchgrabSafe();
4869
6116
  if (!glitchgrab) return null;
4870
6117
  const handleClick = async () => {
@@ -4873,7 +6120,7 @@ function ReportButton({
4873
6120
  setCapturing(false);
4874
6121
  };
4875
6122
  if (children) {
4876
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children: children({ onClick: handleClick, capturing }) });
6123
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_jsx_runtime6.Fragment, { children: children({ onClick: handleClick, capturing }) });
4877
6124
  }
4878
6125
  const isTop = (_a = position == null ? void 0 : position.startsWith("top")) != null ? _a : false;
4879
6126
  const isLeft = (_b = position == null ? void 0 : position.endsWith("left")) != null ? _b : false;
@@ -4881,7 +6128,7 @@ function ReportButton({
4881
6128
  ...isLeft ? { left: "16px" } : { right: "16px" },
4882
6129
  ...isTop ? { top: "16px" } : { bottom: "16px" }
4883
6130
  };
4884
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
6131
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
4885
6132
  "button",
4886
6133
  {
4887
6134
  type: "button",
@@ -4916,7 +6163,7 @@ function ReportButton({
4916
6163
  },
4917
6164
  "aria-label": label,
4918
6165
  children: [
4919
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6166
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4920
6167
  "svg",
4921
6168
  {
4922
6169
  width: "16",
@@ -4924,7 +6171,7 @@ function ReportButton({
4924
6171
  viewBox: "0 0 16 16",
4925
6172
  fill: "none",
4926
6173
  style: { flexShrink: 0 },
4927
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6174
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4928
6175
  "path",
4929
6176
  {
4930
6177
  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",
@@ -4940,15 +6187,15 @@ function ReportButton({
4940
6187
  }
4941
6188
 
4942
6189
  // src/book-demo-button.tsx
4943
- var import_jsx_runtime6 = require("react/jsx-runtime");
6190
+ var import_jsx_runtime7 = require("react/jsx-runtime");
4944
6191
  function BookDemoButton({
4945
6192
  label = "Book a demo",
4946
6193
  className,
4947
6194
  children
4948
6195
  }) {
4949
6196
  const { openBookingDialog } = useGlitchgrab();
4950
- if (children) return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_jsx_runtime6.Fragment, { children: children({ onClick: openBookingDialog }) });
4951
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
6197
+ if (children) return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_jsx_runtime7.Fragment, { children: children({ onClick: openBookingDialog }) });
6198
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4952
6199
  "button",
4953
6200
  {
4954
6201
  type: "button",
@@ -4970,7 +6217,7 @@ function BookDemoButton({
4970
6217
  }
4971
6218
 
4972
6219
  // src/feedback-button.tsx
4973
- var import_jsx_runtime7 = require("react/jsx-runtime");
6220
+ var import_jsx_runtime8 = require("react/jsx-runtime");
4974
6221
  function useGlitchgrabSafe2() {
4975
6222
  try {
4976
6223
  return useGlitchgrab();
@@ -4989,7 +6236,7 @@ function FeedbackButton({
4989
6236
  if (!glitchgrab) return null;
4990
6237
  const handleClick = () => glitchgrab.openFeedbackDialog();
4991
6238
  if (children) {
4992
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_jsx_runtime7.Fragment, { children: children({ onClick: handleClick }) });
6239
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_jsx_runtime8.Fragment, { children: children({ onClick: handleClick }) });
4993
6240
  }
4994
6241
  const isTop = (_a = position == null ? void 0 : position.startsWith("top")) != null ? _a : false;
4995
6242
  const isLeft = (_b = position == null ? void 0 : position.endsWith("left")) != null ? _b : false;
@@ -4997,7 +6244,7 @@ function FeedbackButton({
4997
6244
  ...isLeft ? { left: "16px" } : { right: "16px" },
4998
6245
  ...isTop ? { top: "16px" } : { bottom: "16px" }
4999
6246
  };
5000
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
6247
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
5001
6248
  "button",
5002
6249
  {
5003
6250
  type: "button",
@@ -5030,7 +6277,7 @@ function FeedbackButton({
5030
6277
  },
5031
6278
  "aria-label": label,
5032
6279
  children: [
5033
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
6280
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5034
6281
  "svg",
5035
6282
  {
5036
6283
  width: "16",
@@ -5039,7 +6286,7 @@ function FeedbackButton({
5039
6286
  fill: "none",
5040
6287
  style: { flexShrink: 0 },
5041
6288
  "aria-hidden": "true",
5042
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
6289
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5043
6290
  "path",
5044
6291
  {
5045
6292
  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",
@@ -5055,18 +6302,18 @@ function FeedbackButton({
5055
6302
  }
5056
6303
 
5057
6304
  // src/use-reports.ts
5058
- var import_react6 = require("react");
6305
+ var import_react7 = require("react");
5059
6306
  var BASE_URL = "https://glitchgrab.dev";
5060
6307
  function useGlitchgrabReports({
5061
6308
  token,
5062
6309
  userId,
5063
6310
  limit = 100
5064
6311
  }) {
5065
- const [reports, setReports] = (0, import_react6.useState)([]);
5066
- const [isLoading, setIsLoading] = (0, import_react6.useState)(true);
5067
- const [isFetching, setIsFetching] = (0, import_react6.useState)(false);
5068
- const [error, setError] = (0, import_react6.useState)(null);
5069
- const fetchReports = (0, import_react6.useCallback)(async () => {
6312
+ const [reports, setReports] = (0, import_react7.useState)([]);
6313
+ const [isLoading, setIsLoading] = (0, import_react7.useState)(true);
6314
+ const [isFetching, setIsFetching] = (0, import_react7.useState)(false);
6315
+ const [error, setError] = (0, import_react7.useState)(null);
6316
+ const fetchReports = (0, import_react7.useCallback)(async () => {
5070
6317
  var _a, _b;
5071
6318
  if (!token || !userId) {
5072
6319
  setIsLoading(false);
@@ -5092,7 +6339,7 @@ function useGlitchgrabReports({
5092
6339
  setIsFetching(false);
5093
6340
  }
5094
6341
  }, [token, userId, limit]);
5095
- (0, import_react6.useEffect)(() => {
6342
+ (0, import_react7.useEffect)(() => {
5096
6343
  fetchReports();
5097
6344
  }, [fetchReports]);
5098
6345
  return { reports, isLoading, isFetching, error, refetch: fetchReports };
@@ -5129,9 +6376,9 @@ function useGlitchgrabActions({
5129
6376
  onSuccess,
5130
6377
  onError
5131
6378
  }) {
5132
- const [isPending, setIsPending] = (0, import_react6.useState)(false);
5133
- const [error, setError] = (0, import_react6.useState)(null);
5134
- const run = (0, import_react6.useCallback)(
6379
+ const [isPending, setIsPending] = (0, import_react7.useState)(false);
6380
+ const [error, setError] = (0, import_react7.useState)(null);
6381
+ const run = (0, import_react7.useCallback)(
5135
6382
  async (reportId, body) => {
5136
6383
  setIsPending(true);
5137
6384
  setError(null);
@@ -5161,7 +6408,7 @@ function useGlitchgrabActions({
5161
6408
  }
5162
6409
 
5163
6410
  // src/use-feedback.ts
5164
- var import_react7 = require("react");
6411
+ var import_react8 = require("react");
5165
6412
  var DEFAULT_BASE_URL3 = "https://glitchgrab.dev";
5166
6413
  function buildUrl({
5167
6414
  approvedOnly,
@@ -5187,11 +6434,11 @@ async function fetchGlitchgrabFeedback(query) {
5187
6434
  }
5188
6435
  function useGlitchgrabFeedback(query) {
5189
6436
  const { token, approvedOnly, userId, minRating, limit, baseUrl } = query;
5190
- const [feedback, setFeedback] = (0, import_react7.useState)([]);
5191
- const [isLoading, setIsLoading] = (0, import_react7.useState)(true);
5192
- const [isFetching, setIsFetching] = (0, import_react7.useState)(false);
5193
- const [error, setError] = (0, import_react7.useState)(null);
5194
- const load = (0, import_react7.useCallback)(async () => {
6437
+ const [feedback, setFeedback] = (0, import_react8.useState)([]);
6438
+ const [isLoading, setIsLoading] = (0, import_react8.useState)(true);
6439
+ const [isFetching, setIsFetching] = (0, import_react8.useState)(false);
6440
+ const [error, setError] = (0, import_react8.useState)(null);
6441
+ const load = (0, import_react8.useCallback)(async () => {
5195
6442
  if (!token) {
5196
6443
  setIsLoading(false);
5197
6444
  return;
@@ -5215,7 +6462,7 @@ function useGlitchgrabFeedback(query) {
5215
6462
  setIsFetching(false);
5216
6463
  }
5217
6464
  }, [token, approvedOnly, userId, minRating, limit, baseUrl]);
5218
- (0, import_react7.useEffect)(() => {
6465
+ (0, import_react8.useEffect)(() => {
5219
6466
  load();
5220
6467
  }, [load]);
5221
6468
  return { feedback, isLoading, isFetching, error, refetch: load };