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.mjs CHANGED
@@ -4,11 +4,11 @@
4
4
  import {
5
5
  createContext,
6
6
  useContext,
7
- useRef as useRef3,
8
- useEffect as useEffect4,
7
+ useRef as useRef4,
8
+ useEffect as useEffect5,
9
9
  useCallback as useCallback2,
10
10
  useMemo as useMemo2,
11
- useState as useState4
11
+ useState as useState5
12
12
  } from "react";
13
13
 
14
14
  // src/error-boundary.tsx
@@ -587,6 +587,46 @@ async function enhanceText(text, token, baseUrl, screenshot, context) {
587
587
  return text;
588
588
  }
589
589
  }
590
+ async function assistTurn(params, token, baseUrl) {
591
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
592
+ const offline = {
593
+ conversationId: null,
594
+ question: null,
595
+ report: null,
596
+ degraded: "The assistant is unavailable \u2014 write your report below and send it as normal."
597
+ };
598
+ try {
599
+ const url = `${baseUrl != null ? baseUrl : DEFAULT_BASE_URL}/api/v1/ai/report-chat`;
600
+ const response = await fetch(url, {
601
+ method: "POST",
602
+ headers: {
603
+ "Content-Type": "application/json",
604
+ Authorization: `Bearer ${token}`
605
+ },
606
+ body: JSON.stringify(params)
607
+ });
608
+ const envelope = await response.json().catch(() => null);
609
+ if (!response.ok || !(envelope == null ? void 0 : envelope.success)) {
610
+ return {
611
+ conversationId: null,
612
+ question: null,
613
+ report: null,
614
+ degraded: (_a = envelope == null ? void 0 : envelope.error) != null ? _a : offline.degraded
615
+ };
616
+ }
617
+ return {
618
+ conversationId: (_c = (_b = envelope.data) == null ? void 0 : _b.conversationId) != null ? _c : null,
619
+ question: (_e = (_d = envelope.data) == null ? void 0 : _d.question) != null ? _e : null,
620
+ options: (_g = (_f = envelope.data) == null ? void 0 : _f.options) != null ? _g : [],
621
+ report: (_i = (_h = envelope.data) == null ? void 0 : _h.report) != null ? _i : null,
622
+ duplicate: (_k = (_j = envelope.data) == null ? void 0 : _j.duplicate) != null ? _k : null,
623
+ solved: (_m = (_l = envelope.data) == null ? void 0 : _l.solved) != null ? _m : null,
624
+ degraded: null
625
+ };
626
+ } catch (e) {
627
+ return offline;
628
+ }
629
+ }
590
630
  async function transcribeAudio(blob, token, baseUrl) {
591
631
  var _a;
592
632
  try {
@@ -795,14 +835,17 @@ var GlitchgrabErrorBoundary = class extends React.Component {
795
835
 
796
836
  // ../report-ui/dist/index.mjs
797
837
  import {
798
- useState as useState2,
799
- useRef as useRef2,
800
- useEffect as useEffect2
838
+ useState as useState3,
839
+ useRef as useRef3,
840
+ useEffect as useEffect3
801
841
  } from "react";
802
- import { createPortal } from "react-dom";
842
+ import { createPortal as createPortal2 } from "react-dom";
803
843
  import { useEffect, useRef, useState } from "react";
804
844
  import { jsx, jsxs } from "react/jsx-runtime";
845
+ import { useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
846
+ import { createPortal } from "react-dom";
805
847
  import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
848
+ import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
806
849
  var MAX_SCREENSHOT_DATA_URL_LENGTH = 18e5;
807
850
  var QUALITY_LADDER = [0.92, 0.85, 0.75];
808
851
  var DOWNSCALE_FACTOR = 0.7;
@@ -1103,9 +1146,1058 @@ function AnnotationCanvas({ imageSrc, onSave, onCancel }) {
1103
1146
  children: "Save annotation"
1104
1147
  }
1105
1148
  )
1106
- ] })
1107
- ]
1108
- }
1149
+ ] })
1150
+ ]
1151
+ }
1152
+ );
1153
+ }
1154
+ function getTypeLabel(type) {
1155
+ switch (type) {
1156
+ case "RATING":
1157
+ return "Rating";
1158
+ case "BUG":
1159
+ return "Bug Report";
1160
+ case "FEATURE_REQUEST":
1161
+ return "Feature Request";
1162
+ case "UI_IMPROVEMENT":
1163
+ return "UI Improvement";
1164
+ case "PERFORMANCE":
1165
+ return "Performance";
1166
+ case "SECURITY":
1167
+ return "Security";
1168
+ case "QUESTION":
1169
+ return "Question";
1170
+ case "OTHER":
1171
+ return "Other";
1172
+ }
1173
+ }
1174
+ var STARTERS = [
1175
+ "Something on this page is broken",
1176
+ "It did the wrong thing",
1177
+ "I wish it could\u2026"
1178
+ ];
1179
+ var NARROW_QUERY = "(max-width: 640px)";
1180
+ function useIsNarrow() {
1181
+ const [narrow, setNarrow] = useState2(false);
1182
+ useEffect2(() => {
1183
+ try {
1184
+ const mq = window.matchMedia(NARROW_QUERY);
1185
+ setNarrow(mq.matches);
1186
+ const onChange = (e) => setNarrow(e.matches);
1187
+ mq.addEventListener("change", onChange);
1188
+ return () => mq.removeEventListener("change", onChange);
1189
+ } catch (e) {
1190
+ }
1191
+ }, []);
1192
+ return narrow;
1193
+ }
1194
+ function Sparkle({ color, size = 14 }) {
1195
+ return /* @__PURE__ */ jsx2("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx2(
1196
+ "path",
1197
+ {
1198
+ 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",
1199
+ stroke: color,
1200
+ strokeWidth: "1.5",
1201
+ strokeLinejoin: "round"
1202
+ }
1203
+ ) });
1204
+ }
1205
+ function Avatar({
1206
+ who,
1207
+ theme: t2,
1208
+ initials
1209
+ }) {
1210
+ const isAi = who === "assistant";
1211
+ return /* @__PURE__ */ jsx2(
1212
+ "span",
1213
+ {
1214
+ "aria-hidden": "true",
1215
+ style: {
1216
+ flexShrink: 0,
1217
+ width: "24px",
1218
+ height: "24px",
1219
+ borderRadius: "50%",
1220
+ display: "inline-flex",
1221
+ alignItems: "center",
1222
+ justifyContent: "center",
1223
+ marginTop: "2px",
1224
+ backgroundColor: isAi ? `${t2.accent}22` : t2.bgSecondary,
1225
+ border: `1px solid ${isAi ? t2.accent : t2.inputBorder}`,
1226
+ color: isAi ? t2.accent : t2.textMuted,
1227
+ fontSize: "10px",
1228
+ fontWeight: 700
1229
+ },
1230
+ children: isAi ? /* @__PURE__ */ jsx2(Sparkle, { color: t2.accent, size: 12 }) : initials ? initials : /* @__PURE__ */ jsxs2("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: [
1231
+ /* @__PURE__ */ jsx2("circle", { cx: "12", cy: "8", r: "3.4", stroke: "currentColor", strokeWidth: "1.8" }),
1232
+ /* @__PURE__ */ jsx2(
1233
+ "path",
1234
+ {
1235
+ d: "M5 20c0-3.6 3.1-5.6 7-5.6s7 2 7 5.6",
1236
+ stroke: "currentColor",
1237
+ strokeWidth: "1.8",
1238
+ strokeLinecap: "round"
1239
+ }
1240
+ )
1241
+ ] })
1242
+ }
1243
+ );
1244
+ }
1245
+ function AssistSheet({
1246
+ assist,
1247
+ theme: t2,
1248
+ screenshot,
1249
+ attachmentCount,
1250
+ context,
1251
+ reportTypeLabel,
1252
+ typePicked,
1253
+ currentTile,
1254
+ tiles,
1255
+ onPickType,
1256
+ rating,
1257
+ onRatingChange,
1258
+ projectSlot,
1259
+ reporterName,
1260
+ description,
1261
+ onDescriptionChange,
1262
+ severity,
1263
+ onSeverityChange,
1264
+ showSeverity,
1265
+ onDuplicateChange,
1266
+ isSubmitting,
1267
+ submitted,
1268
+ onSend,
1269
+ onDegrade,
1270
+ onClose,
1271
+ onFinish
1272
+ }) {
1273
+ const narrow = useIsNarrow();
1274
+ const [messages, setMessages] = useState2([]);
1275
+ const [input, setInput] = useState2("");
1276
+ const [busy, setBusy] = useState2(false);
1277
+ const [conversationId, setConversationId] = useState2(null);
1278
+ const [hoveredStar, setHoveredStar] = useState2(0);
1279
+ const [options, setOptions] = useState2([]);
1280
+ const [duplicate, setDuplicate] = useState2(null);
1281
+ const [solved, setSolved] = useState2(null);
1282
+ const [phase, setPhase] = useState2(
1283
+ !typePicked ? "type" : currentTile === "RATING" ? "rating" : "chat"
1284
+ );
1285
+ const scrollRef = useRef2(null);
1286
+ const inputRef = useRef2(null);
1287
+ const draftRef = useRef2(null);
1288
+ const seededRef = useRef2(false);
1289
+ useEffect2(() => {
1290
+ const el = scrollRef.current;
1291
+ if (el) el.scrollTop = el.scrollHeight;
1292
+ }, [messages, busy, phase]);
1293
+ useEffect2(() => {
1294
+ var _a;
1295
+ if (phase === "draft") (_a = draftRef.current) == null ? void 0 : _a.focus();
1296
+ }, [phase]);
1297
+ async function runTurn(history2) {
1298
+ var _a, _b, _c, _d;
1299
+ setBusy(true);
1300
+ let result;
1301
+ try {
1302
+ result = await assist({ messages: history2, conversationId, screenshot, context });
1303
+ } catch (e) {
1304
+ onDegrade("The assistant is unavailable \u2014 write your report below and send it as normal.");
1305
+ return;
1306
+ } finally {
1307
+ setBusy(false);
1308
+ }
1309
+ if (result.degraded) {
1310
+ onDegrade(result.degraded);
1311
+ return;
1312
+ }
1313
+ if (result.conversationId) setConversationId(result.conversationId);
1314
+ setDuplicate((_a = result.duplicate) != null ? _a : null);
1315
+ onDuplicateChange == null ? void 0 : onDuplicateChange((_c = (_b = result.duplicate) == null ? void 0 : _b.number) != null ? _c : null);
1316
+ if (result.solved) {
1317
+ setSolved(result.solved);
1318
+ setOptions([]);
1319
+ setPhase("solved");
1320
+ return;
1321
+ }
1322
+ if (result.report) {
1323
+ onDescriptionChange(result.report);
1324
+ setMessages([...history2, { role: "assistant", content: "Here's your report \u2014 have a read." }]);
1325
+ setOptions([]);
1326
+ setPhase("draft");
1327
+ return;
1328
+ }
1329
+ if (result.question) {
1330
+ setMessages([...history2, { role: "assistant", content: result.question }]);
1331
+ setOptions((_d = result.options) != null ? _d : []);
1332
+ return;
1333
+ }
1334
+ onDegrade("The assistant had nothing to add \u2014 write your report below and send it as normal.");
1335
+ }
1336
+ useEffect2(() => {
1337
+ if (seededRef.current) return;
1338
+ seededRef.current = true;
1339
+ if (!typePicked || currentTile === "RATING") return;
1340
+ const seed = description.trim();
1341
+ if (!seed) return;
1342
+ const history2 = [{ role: "user", content: seed }];
1343
+ setMessages(history2);
1344
+ void runTurn(history2);
1345
+ }, []);
1346
+ function send(text) {
1347
+ const value = text.trim();
1348
+ if (!value || busy) return;
1349
+ setOptions([]);
1350
+ const history2 = [...messages, { role: "user", content: value }];
1351
+ setMessages(history2);
1352
+ setInput("");
1353
+ void runTurn(history2);
1354
+ }
1355
+ function pickType(tile) {
1356
+ onPickType(tile);
1357
+ setPhase(tile === "RATING" ? "rating" : "chat");
1358
+ }
1359
+ const empty = phase === "chat" && messages.length === 0 && !busy;
1360
+ const initials = (reporterName != null ? reporterName : "").split(/\s+/).filter(Boolean).slice(0, 2).map((w) => {
1361
+ var _a, _b;
1362
+ return (_b = (_a = w[0]) == null ? void 0 : _a.toUpperCase()) != null ? _b : "";
1363
+ }).join("");
1364
+ const panelStyle = narrow ? {
1365
+ width: "100%",
1366
+ maxHeight: "88dvh",
1367
+ borderTopLeftRadius: "16px",
1368
+ borderTopRightRadius: "16px",
1369
+ animation: "gg-sheet-up .22s cubic-bezier(.2,.8,.2,1)"
1370
+ } : {
1371
+ width: "440px",
1372
+ maxWidth: "100%",
1373
+ height: "100dvh",
1374
+ borderLeft: `1px solid ${t2.border}`,
1375
+ animation: "gg-sheet-in .22s cubic-bezier(.2,.8,.2,1)"
1376
+ };
1377
+ return createPortal(
1378
+ /* @__PURE__ */ jsxs2(Fragment, { children: [
1379
+ /* @__PURE__ */ jsx2("style", { children: `
1380
+ @keyframes gg-sheet-in{from{transform:translateX(24px);opacity:0}to{transform:translateX(0);opacity:1}}
1381
+ @keyframes gg-sheet-up{from{transform:translateY(24px);opacity:0}to{transform:translateY(0);opacity:1}}
1382
+ @keyframes gg-sheet-fade{from{opacity:0}to{opacity:1}}
1383
+ @keyframes gg-dot{0%,80%,100%{transform:translateY(0);opacity:.4}40%{transform:translateY(-3px);opacity:1}}
1384
+ [data-gg-sheet-send]:focus-visible,[data-gg-chip]:focus-visible{outline:2px solid currentColor;outline-offset:2px}
1385
+ ` }),
1386
+ /* @__PURE__ */ jsx2(
1387
+ "div",
1388
+ {
1389
+ "data-glitchgrab-layer": "",
1390
+ role: "dialog",
1391
+ "aria-modal": "true",
1392
+ "aria-label": "Describe your report with AI",
1393
+ style: {
1394
+ position: "fixed",
1395
+ inset: 0,
1396
+ zIndex: 2147483647,
1397
+ display: "flex",
1398
+ alignItems: narrow ? "flex-end" : "stretch",
1399
+ justifyContent: narrow ? "center" : "flex-end",
1400
+ backgroundColor: "rgba(0,0,0,0.5)",
1401
+ animation: "gg-sheet-fade .18s ease",
1402
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
1403
+ },
1404
+ onClick: onClose,
1405
+ onPointerDown: (e) => e.stopPropagation(),
1406
+ children: /* @__PURE__ */ jsxs2(
1407
+ "div",
1408
+ {
1409
+ onClick: (e) => e.stopPropagation(),
1410
+ style: {
1411
+ ...panelStyle,
1412
+ display: "flex",
1413
+ flexDirection: "column",
1414
+ // A flex child defaults to min-width:auto, so a long chat bubble
1415
+ // grows the sheet past the viewport instead of wrapping inside it.
1416
+ // This is what keeps the bottom sheet on screen.
1417
+ minWidth: 0,
1418
+ maxWidth: "100%",
1419
+ boxSizing: "border-box",
1420
+ backgroundColor: t2.bg,
1421
+ color: t2.text,
1422
+ boxShadow: "0 20px 60px rgba(0,0,0,.35)",
1423
+ overflow: "hidden",
1424
+ isolation: "isolate"
1425
+ },
1426
+ children: [
1427
+ /* @__PURE__ */ jsxs2(
1428
+ "div",
1429
+ {
1430
+ style: {
1431
+ flexShrink: 0,
1432
+ padding: "14px 16px",
1433
+ borderBottom: `1px solid ${t2.border}`,
1434
+ display: "flex",
1435
+ alignItems: "flex-start",
1436
+ justifyContent: "space-between",
1437
+ gap: "12px",
1438
+ minWidth: 0
1439
+ },
1440
+ children: [
1441
+ /* @__PURE__ */ jsxs2("div", { style: { minWidth: 0, overflow: "hidden" }, children: [
1442
+ /* @__PURE__ */ jsxs2(
1443
+ "div",
1444
+ {
1445
+ style: {
1446
+ display: "flex",
1447
+ alignItems: "center",
1448
+ gap: "7px",
1449
+ fontSize: "14px",
1450
+ fontWeight: 600
1451
+ },
1452
+ children: [
1453
+ /* @__PURE__ */ jsx2(Sparkle, { color: t2.accent }),
1454
+ "Describe it with AI",
1455
+ /* @__PURE__ */ jsx2(
1456
+ "span",
1457
+ {
1458
+ style: {
1459
+ fontSize: "10px",
1460
+ fontWeight: 600,
1461
+ letterSpacing: ".04em",
1462
+ textTransform: "uppercase",
1463
+ color: t2.accent,
1464
+ border: `1px solid ${t2.accent}55`,
1465
+ borderRadius: "4px",
1466
+ padding: "1px 5px"
1467
+ },
1468
+ children: "Beta"
1469
+ }
1470
+ )
1471
+ ]
1472
+ }
1473
+ ),
1474
+ /* @__PURE__ */ jsxs2("div", { style: { fontSize: "11.5px", color: t2.textMuted, marginTop: "3px" }, children: [
1475
+ phase === "type" ? null : reportTypeLabel,
1476
+ projectSlot ? /* @__PURE__ */ jsx2("span", { style: { marginLeft: "6px" }, children: projectSlot }) : null
1477
+ ] })
1478
+ ] }),
1479
+ /* @__PURE__ */ jsx2(
1480
+ "button",
1481
+ {
1482
+ type: "button",
1483
+ onClick: onClose,
1484
+ "aria-label": "Close and write it myself",
1485
+ style: {
1486
+ flexShrink: 0,
1487
+ border: "none",
1488
+ background: "transparent",
1489
+ color: t2.textMuted,
1490
+ cursor: "pointer",
1491
+ fontSize: narrow ? "18px" : "12px",
1492
+ lineHeight: 1,
1493
+ fontFamily: "inherit",
1494
+ padding: narrow ? "4px 6px" : "6px 4px"
1495
+ },
1496
+ children: narrow ? "\xD7" : "Write it myself"
1497
+ }
1498
+ )
1499
+ ]
1500
+ }
1501
+ ),
1502
+ /* @__PURE__ */ jsx2(
1503
+ "div",
1504
+ {
1505
+ ref: scrollRef,
1506
+ style: {
1507
+ flex: 1,
1508
+ minHeight: narrow ? "180px" : 0,
1509
+ overflowY: "auto",
1510
+ padding: "16px",
1511
+ display: "flex",
1512
+ flexDirection: "column"
1513
+ },
1514
+ children: /* @__PURE__ */ jsxs2(
1515
+ "div",
1516
+ {
1517
+ style: {
1518
+ marginTop: "auto",
1519
+ display: "flex",
1520
+ flexDirection: "column",
1521
+ gap: "12px",
1522
+ minWidth: 0
1523
+ },
1524
+ children: [
1525
+ phase === "type" && /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
1526
+ /* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "8px" }, children: [
1527
+ /* @__PURE__ */ jsx2(Avatar, { who: "assistant", theme: t2 }),
1528
+ /* @__PURE__ */ jsxs2(
1529
+ "div",
1530
+ {
1531
+ style: {
1532
+ padding: "9px 12px",
1533
+ borderRadius: "12px 12px 12px 4px",
1534
+ backgroundColor: t2.bgSecondary,
1535
+ fontSize: "13px",
1536
+ lineHeight: 1.55,
1537
+ maxWidth: "88%"
1538
+ },
1539
+ children: [
1540
+ reporterName ? `Hi ${reporterName.split(" ")[0]} \u2014 w` : "W",
1541
+ "hat do you want to do? Pick one and I'll take it from there."
1542
+ ]
1543
+ }
1544
+ )
1545
+ ] }),
1546
+ /* @__PURE__ */ jsx2(
1547
+ "div",
1548
+ {
1549
+ style: {
1550
+ display: "flex",
1551
+ flexWrap: "wrap",
1552
+ gap: "6px",
1553
+ paddingLeft: "32px"
1554
+ },
1555
+ children: tiles.map((tile) => {
1556
+ const rate = tile === "RATING";
1557
+ return /* @__PURE__ */ jsx2(
1558
+ "button",
1559
+ {
1560
+ type: "button",
1561
+ "data-gg-chip": "",
1562
+ "data-gg-tile": tile,
1563
+ onClick: () => pickType(tile),
1564
+ style: {
1565
+ display: "inline-flex",
1566
+ alignItems: "center",
1567
+ gap: "5px",
1568
+ // The rating is the only tile that isn't a report, so
1569
+ // it wears the star colour the dialog's hero row uses
1570
+ // rather than hiding among the report types.
1571
+ border: `1px solid ${rate ? "rgba(245,158,11,0.5)" : t2.inputBorder}`,
1572
+ background: rate ? "rgba(245,158,11,0.08)" : "transparent",
1573
+ color: rate ? "#f59e0b" : t2.textMuted,
1574
+ borderRadius: "999px",
1575
+ // 8px vertical keeps the tap target at ~32px.
1576
+ padding: "8px 12px",
1577
+ fontSize: "12px",
1578
+ fontWeight: rate ? 600 : 400,
1579
+ fontFamily: "inherit",
1580
+ cursor: "pointer"
1581
+ },
1582
+ children: rate ? "\u2605 Rate us" : getTypeLabel(tile)
1583
+ },
1584
+ tile
1585
+ );
1586
+ })
1587
+ }
1588
+ )
1589
+ ] }),
1590
+ phase === "rating" && !submitted && /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
1591
+ /* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "8px" }, children: [
1592
+ /* @__PURE__ */ jsx2(Avatar, { who: "assistant", theme: t2 }),
1593
+ /* @__PURE__ */ jsx2(
1594
+ "div",
1595
+ {
1596
+ style: {
1597
+ padding: "9px 12px",
1598
+ borderRadius: "12px 12px 12px 4px",
1599
+ backgroundColor: t2.bgSecondary,
1600
+ fontSize: "13px",
1601
+ lineHeight: 1.55,
1602
+ maxWidth: "88%"
1603
+ },
1604
+ children: "How are we doing? Tap a star \u2014 the words are optional."
1605
+ }
1606
+ )
1607
+ ] }),
1608
+ /* @__PURE__ */ jsxs2(
1609
+ "div",
1610
+ {
1611
+ style: {
1612
+ display: "flex",
1613
+ flexDirection: "column",
1614
+ gap: "10px",
1615
+ marginLeft: "32px",
1616
+ padding: "12px",
1617
+ borderRadius: "12px",
1618
+ border: "1px solid rgba(245,158,11,0.4)",
1619
+ backgroundColor: "rgba(245,158,11,0.06)"
1620
+ },
1621
+ children: [
1622
+ /* @__PURE__ */ jsx2("div", { style: { display: "flex", gap: "4px" }, role: "group", "aria-label": "Rating", children: [1, 2, 3, 4, 5].map((star) => {
1623
+ const filled = star <= (hoveredStar || rating);
1624
+ return /* @__PURE__ */ jsx2(
1625
+ "button",
1626
+ {
1627
+ type: "button",
1628
+ "aria-label": `${star} star${star > 1 ? "s" : ""}`,
1629
+ "aria-pressed": star <= rating,
1630
+ onClick: () => onRatingChange(star),
1631
+ onMouseEnter: () => setHoveredStar(star),
1632
+ onMouseLeave: () => setHoveredStar(0),
1633
+ style: {
1634
+ border: "none",
1635
+ background: "transparent",
1636
+ padding: 0,
1637
+ cursor: "pointer",
1638
+ lineHeight: 0
1639
+ },
1640
+ children: /* @__PURE__ */ jsx2("svg", { width: "30", height: "30", viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ jsx2(
1641
+ "path",
1642
+ {
1643
+ 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",
1644
+ fill: filled ? "#f59e0b" : "transparent",
1645
+ stroke: filled ? "#f59e0b" : t2.inputBorder,
1646
+ strokeWidth: "1.5",
1647
+ strokeLinejoin: "round"
1648
+ }
1649
+ ) })
1650
+ },
1651
+ star
1652
+ );
1653
+ }) }),
1654
+ /* @__PURE__ */ jsx2(
1655
+ "textarea",
1656
+ {
1657
+ value: description,
1658
+ onChange: (e) => onDescriptionChange(e.target.value),
1659
+ rows: 3,
1660
+ placeholder: "What made it good \u2014 or what let you down? (optional)",
1661
+ style: {
1662
+ width: "100%",
1663
+ padding: "10px",
1664
+ borderRadius: "8px",
1665
+ border: `1px solid ${t2.inputBorder}`,
1666
+ backgroundColor: t2.inputBg,
1667
+ color: t2.text,
1668
+ fontSize: "13px",
1669
+ lineHeight: 1.5,
1670
+ fontFamily: "inherit",
1671
+ resize: "vertical",
1672
+ outline: "none",
1673
+ boxSizing: "border-box"
1674
+ }
1675
+ }
1676
+ ),
1677
+ /* @__PURE__ */ jsx2(
1678
+ "button",
1679
+ {
1680
+ type: "button",
1681
+ onClick: () => setPhase("type"),
1682
+ style: {
1683
+ alignSelf: "flex-start",
1684
+ border: "none",
1685
+ background: "transparent",
1686
+ color: t2.textMuted,
1687
+ fontSize: "12px",
1688
+ fontFamily: "inherit",
1689
+ // A bare text link is ~14px tall — half a thumb.
1690
+ padding: "9px 0",
1691
+ cursor: "pointer",
1692
+ textDecoration: "underline"
1693
+ },
1694
+ children: "Report something instead"
1695
+ }
1696
+ )
1697
+ ]
1698
+ }
1699
+ )
1700
+ ] }),
1701
+ empty && /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
1702
+ /* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "8px" }, children: [
1703
+ /* @__PURE__ */ jsx2(Avatar, { who: "assistant", theme: t2 }),
1704
+ /* @__PURE__ */ jsxs2(
1705
+ "div",
1706
+ {
1707
+ style: {
1708
+ padding: "9px 12px",
1709
+ borderRadius: "12px 12px 12px 4px",
1710
+ backgroundColor: t2.bgSecondary,
1711
+ fontSize: "13px",
1712
+ lineHeight: 1.55,
1713
+ maxWidth: "88%"
1714
+ },
1715
+ children: [
1716
+ reporterName ? `Hi ${reporterName.split(" ")[0]} \u2014 t` : "T",
1717
+ "ell me what went wrong in your own words. I can already see your screenshot and what you clicked, so skip the boring parts."
1718
+ ]
1719
+ }
1720
+ )
1721
+ ] }),
1722
+ /* @__PURE__ */ jsx2(
1723
+ "div",
1724
+ {
1725
+ style: {
1726
+ display: "flex",
1727
+ flexWrap: "wrap",
1728
+ gap: "6px",
1729
+ paddingLeft: "32px"
1730
+ },
1731
+ children: STARTERS.map((s) => /* @__PURE__ */ jsx2(
1732
+ "button",
1733
+ {
1734
+ type: "button",
1735
+ "data-gg-chip": "",
1736
+ onClick: () => send(s),
1737
+ style: {
1738
+ border: `1px solid ${t2.inputBorder}`,
1739
+ background: "transparent",
1740
+ color: t2.textMuted,
1741
+ borderRadius: "999px",
1742
+ padding: "6px 11px",
1743
+ fontSize: "12px",
1744
+ fontFamily: "inherit",
1745
+ cursor: "pointer"
1746
+ },
1747
+ children: s
1748
+ },
1749
+ s
1750
+ ))
1751
+ }
1752
+ )
1753
+ ] }),
1754
+ messages.map((m, i) => {
1755
+ const mine = m.role === "user";
1756
+ return /* @__PURE__ */ jsxs2(
1757
+ "div",
1758
+ {
1759
+ style: {
1760
+ display: "flex",
1761
+ gap: "8px",
1762
+ minWidth: 0,
1763
+ flexDirection: mine ? "row-reverse" : "row"
1764
+ },
1765
+ children: [
1766
+ /* @__PURE__ */ jsx2(Avatar, { who: m.role, theme: t2, initials }),
1767
+ /* @__PURE__ */ jsx2(
1768
+ "div",
1769
+ {
1770
+ style: {
1771
+ maxWidth: "82%",
1772
+ padding: "9px 12px",
1773
+ borderRadius: mine ? "12px 12px 4px 12px" : "12px 12px 12px 4px",
1774
+ fontSize: "13px",
1775
+ lineHeight: 1.55,
1776
+ whiteSpace: "pre-wrap",
1777
+ wordBreak: "break-word",
1778
+ backgroundColor: mine ? t2.accent : t2.bgSecondary,
1779
+ color: mine ? t2.accentText : t2.text
1780
+ },
1781
+ children: m.content
1782
+ }
1783
+ )
1784
+ ]
1785
+ },
1786
+ i
1787
+ );
1788
+ }),
1789
+ options.length > 0 && !busy && phase === "chat" && /* @__PURE__ */ jsx2(
1790
+ "div",
1791
+ {
1792
+ style: {
1793
+ display: "flex",
1794
+ // Long labels wrapped into a ragged row that always stranded
1795
+ // the last chip on a line of its own. Past ~24 characters
1796
+ // these stop being chips and become a choice list, so they
1797
+ // stack full width and read like one.
1798
+ flexDirection: options.some((o) => o.length > 24) ? "column" : "row",
1799
+ alignItems: options.some((o) => o.length > 24) ? "stretch" : "flex-start",
1800
+ flexWrap: "wrap",
1801
+ gap: "6px",
1802
+ paddingLeft: "32px"
1803
+ },
1804
+ children: options.map((option) => /* @__PURE__ */ jsx2(
1805
+ "button",
1806
+ {
1807
+ type: "button",
1808
+ "data-gg-chip": "",
1809
+ "data-gg-option": "",
1810
+ onClick: () => send(option),
1811
+ style: {
1812
+ border: `1px solid ${t2.inputBorder}`,
1813
+ background: "transparent",
1814
+ color: t2.textMuted,
1815
+ borderRadius: "999px",
1816
+ // Same 8px as the picker chips — one tap target size in
1817
+ // this sheet, not two.
1818
+ padding: "8px 12px",
1819
+ fontSize: "12px",
1820
+ fontFamily: "inherit",
1821
+ cursor: "pointer",
1822
+ textAlign: "left"
1823
+ },
1824
+ children: option
1825
+ },
1826
+ option
1827
+ ))
1828
+ }
1829
+ ),
1830
+ busy && /* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "8px" }, role: "status", "aria-label": "Thinking", children: [
1831
+ /* @__PURE__ */ jsx2(Avatar, { who: "assistant", theme: t2 }),
1832
+ /* @__PURE__ */ jsx2(
1833
+ "span",
1834
+ {
1835
+ style: {
1836
+ display: "inline-flex",
1837
+ alignItems: "center",
1838
+ gap: "4px",
1839
+ padding: "12px",
1840
+ borderRadius: "12px 12px 12px 4px",
1841
+ backgroundColor: t2.bgSecondary
1842
+ },
1843
+ children: [0, 1, 2].map((i) => /* @__PURE__ */ jsx2(
1844
+ "span",
1845
+ {
1846
+ style: {
1847
+ width: "5px",
1848
+ height: "5px",
1849
+ borderRadius: "50%",
1850
+ backgroundColor: t2.textMuted,
1851
+ animation: `gg-dot 1.1s ease-in-out ${i * 0.15}s infinite`
1852
+ }
1853
+ },
1854
+ i
1855
+ ))
1856
+ }
1857
+ )
1858
+ ] }),
1859
+ phase === "draft" && !submitted && /* @__PURE__ */ jsxs2(
1860
+ "div",
1861
+ {
1862
+ style: {
1863
+ border: `1px solid ${t2.accent}`,
1864
+ borderRadius: "12px",
1865
+ backgroundColor: t2.bgSecondary,
1866
+ padding: "12px",
1867
+ display: "flex",
1868
+ flexDirection: "column",
1869
+ gap: "10px",
1870
+ minWidth: 0,
1871
+ boxSizing: "border-box"
1872
+ },
1873
+ children: [
1874
+ /* @__PURE__ */ jsx2(
1875
+ "span",
1876
+ {
1877
+ style: {
1878
+ fontSize: "10px",
1879
+ fontWeight: 700,
1880
+ letterSpacing: ".06em",
1881
+ textTransform: "uppercase",
1882
+ color: t2.accent
1883
+ },
1884
+ children: "Your report \xB7 edit anything"
1885
+ }
1886
+ ),
1887
+ duplicate && /* @__PURE__ */ jsxs2(
1888
+ "div",
1889
+ {
1890
+ style: {
1891
+ display: "flex",
1892
+ flexDirection: "column",
1893
+ gap: "3px",
1894
+ padding: "9px 10px",
1895
+ borderRadius: "8px",
1896
+ border: "1px solid rgba(245,158,11,0.4)",
1897
+ backgroundColor: "rgba(245,158,11,0.08)",
1898
+ fontSize: "12px",
1899
+ lineHeight: 1.5
1900
+ },
1901
+ children: [
1902
+ /* @__PURE__ */ jsx2("span", { style: { color: "#f59e0b", fontWeight: 600 }, children: "Our team is already on this" }),
1903
+ /* @__PURE__ */ jsxs2("span", { style: { color: t2.textMuted, wordBreak: "break-word" }, children: [
1904
+ "#",
1905
+ duplicate.number,
1906
+ " ",
1907
+ duplicate.title
1908
+ ] }),
1909
+ /* @__PURE__ */ jsx2("span", { style: { color: t2.textMuted }, children: "Your details will be added to it instead of opening a new issue." })
1910
+ ]
1911
+ }
1912
+ ),
1913
+ /* @__PURE__ */ jsx2(
1914
+ "textarea",
1915
+ {
1916
+ ref: draftRef,
1917
+ value: description,
1918
+ onChange: (e) => onDescriptionChange(e.target.value),
1919
+ rows: 6,
1920
+ style: {
1921
+ width: "100%",
1922
+ minHeight: "120px",
1923
+ padding: "10px",
1924
+ borderRadius: "8px",
1925
+ border: `1px solid ${t2.inputBorder}`,
1926
+ backgroundColor: t2.inputBg,
1927
+ color: t2.text,
1928
+ fontSize: "13px",
1929
+ lineHeight: 1.55,
1930
+ fontFamily: "inherit",
1931
+ resize: "vertical",
1932
+ outline: "none",
1933
+ boxSizing: "border-box"
1934
+ }
1935
+ }
1936
+ ),
1937
+ showSeverity && /* @__PURE__ */ jsxs2("div", { children: [
1938
+ /* @__PURE__ */ jsx2(
1939
+ "span",
1940
+ {
1941
+ style: {
1942
+ fontSize: "11.5px",
1943
+ color: t2.textMuted,
1944
+ display: "block",
1945
+ marginBottom: "6px"
1946
+ },
1947
+ children: "How bad is it?"
1948
+ }
1949
+ ),
1950
+ /* @__PURE__ */ jsx2("div", { style: { display: "flex", gap: "6px" }, children: ["low", "medium", "high"].map((s) => {
1951
+ const on = severity === s;
1952
+ return /* @__PURE__ */ jsx2(
1953
+ "button",
1954
+ {
1955
+ type: "button",
1956
+ onClick: () => onSeverityChange(s),
1957
+ "aria-pressed": on,
1958
+ style: {
1959
+ flex: 1,
1960
+ minWidth: 0,
1961
+ padding: "8px 0",
1962
+ borderRadius: "8px",
1963
+ border: `1px solid ${on ? t2.accent : t2.inputBorder}`,
1964
+ backgroundColor: on ? t2.accent : "transparent",
1965
+ color: on ? t2.accentText : t2.textMuted,
1966
+ fontSize: "12px",
1967
+ fontWeight: 600,
1968
+ fontFamily: "inherit",
1969
+ textTransform: "capitalize",
1970
+ cursor: "pointer"
1971
+ },
1972
+ children: s
1973
+ },
1974
+ s
1975
+ );
1976
+ }) })
1977
+ ] }),
1978
+ attachmentCount > 0 && /* @__PURE__ */ jsxs2("span", { style: { fontSize: "11.5px", color: t2.textMuted }, children: [
1979
+ attachmentCount,
1980
+ " ",
1981
+ attachmentCount === 1 ? "attachment" : "attachments",
1982
+ " will be sent with this."
1983
+ ] }),
1984
+ /* @__PURE__ */ jsx2(
1985
+ "button",
1986
+ {
1987
+ type: "button",
1988
+ onClick: () => setPhase("chat"),
1989
+ style: {
1990
+ alignSelf: "flex-start",
1991
+ border: "none",
1992
+ background: "transparent",
1993
+ color: t2.textMuted,
1994
+ fontSize: "12px",
1995
+ fontFamily: "inherit",
1996
+ padding: "9px 0",
1997
+ cursor: "pointer",
1998
+ textDecoration: "underline"
1999
+ },
2000
+ children: "Not quite \u2014 keep chatting"
2001
+ }
2002
+ )
2003
+ ]
2004
+ }
2005
+ ),
2006
+ phase === "solved" && solved && /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
2007
+ /* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "8px" }, children: [
2008
+ /* @__PURE__ */ jsx2(Avatar, { who: "assistant", theme: t2 }),
2009
+ /* @__PURE__ */ jsx2(
2010
+ "div",
2011
+ {
2012
+ style: {
2013
+ padding: "9px 12px",
2014
+ borderRadius: "12px 12px 12px 4px",
2015
+ backgroundColor: t2.bgSecondary,
2016
+ fontSize: "13px",
2017
+ lineHeight: 1.55,
2018
+ maxWidth: "88%",
2019
+ whiteSpace: "pre-wrap"
2020
+ },
2021
+ children: solved
2022
+ }
2023
+ )
2024
+ ] }),
2025
+ /* @__PURE__ */ jsx2(
2026
+ "span",
2027
+ {
2028
+ style: { fontSize: "11.5px", color: t2.textMuted, paddingLeft: "32px" },
2029
+ children: "Nothing was filed \u2014 you are all set."
2030
+ }
2031
+ )
2032
+ ] }),
2033
+ submitted && /* @__PURE__ */ jsxs2(
2034
+ "div",
2035
+ {
2036
+ style: {
2037
+ textAlign: "center",
2038
+ padding: "24px 0",
2039
+ color: t2.accent,
2040
+ fontSize: "14px",
2041
+ fontWeight: 600
2042
+ },
2043
+ children: [
2044
+ reportTypeLabel,
2045
+ " sent. Thank you!"
2046
+ ]
2047
+ }
2048
+ )
2049
+ ]
2050
+ }
2051
+ )
2052
+ }
2053
+ ),
2054
+ !submitted && phase !== "type" && /* @__PURE__ */ jsx2(
2055
+ "div",
2056
+ {
2057
+ style: {
2058
+ flexShrink: 0,
2059
+ borderTop: `1px solid ${t2.border}`,
2060
+ padding: "12px 16px",
2061
+ paddingBottom: narrow ? "max(12px, env(safe-area-inset-bottom))" : "12px",
2062
+ backgroundColor: t2.bg
2063
+ },
2064
+ children: phase === "solved" ? /* @__PURE__ */ jsx2(
2065
+ "button",
2066
+ {
2067
+ type: "button",
2068
+ "data-gg-sheet-send": "",
2069
+ onClick: () => (onFinish != null ? onFinish : onClose)(),
2070
+ style: {
2071
+ width: "100%",
2072
+ padding: "12px",
2073
+ borderRadius: "10px",
2074
+ border: "none",
2075
+ backgroundColor: t2.accent,
2076
+ color: t2.accentText,
2077
+ fontSize: "14px",
2078
+ fontWeight: 700,
2079
+ fontFamily: "inherit",
2080
+ cursor: "pointer"
2081
+ },
2082
+ children: "Done"
2083
+ }
2084
+ ) : phase === "rating" ? /* @__PURE__ */ jsx2(
2085
+ "button",
2086
+ {
2087
+ type: "button",
2088
+ "data-gg-sheet-send": "",
2089
+ onClick: onSend,
2090
+ disabled: isSubmitting || rating < 1,
2091
+ style: {
2092
+ width: "100%",
2093
+ padding: "12px",
2094
+ borderRadius: "10px",
2095
+ border: "none",
2096
+ backgroundColor: isSubmitting || rating < 1 ? t2.bgSecondary : "#f59e0b",
2097
+ color: isSubmitting || rating < 1 ? t2.textMuted : "#1a1a1a",
2098
+ fontSize: "14px",
2099
+ fontWeight: 700,
2100
+ fontFamily: "inherit",
2101
+ cursor: isSubmitting || rating < 1 ? "default" : "pointer"
2102
+ },
2103
+ children: isSubmitting ? "Sending\u2026" : rating < 1 ? "Pick a star first" : "Send Rating"
2104
+ }
2105
+ ) : phase === "draft" ? /* @__PURE__ */ jsx2(
2106
+ "button",
2107
+ {
2108
+ type: "button",
2109
+ "data-gg-sheet-send": "",
2110
+ onClick: onSend,
2111
+ disabled: isSubmitting || !description.trim(),
2112
+ style: {
2113
+ width: "100%",
2114
+ padding: "12px",
2115
+ borderRadius: "10px",
2116
+ border: "none",
2117
+ backgroundColor: isSubmitting || !description.trim() ? t2.bgSecondary : t2.accent,
2118
+ color: isSubmitting || !description.trim() ? t2.textMuted : t2.accentText,
2119
+ fontSize: "14px",
2120
+ fontWeight: 700,
2121
+ fontFamily: "inherit",
2122
+ cursor: isSubmitting || !description.trim() ? "default" : "pointer"
2123
+ },
2124
+ children: isSubmitting ? "Sending\u2026" : duplicate ? `Add to #${duplicate.number}` : "Send Report"
2125
+ }
2126
+ ) : /* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "8px", alignItems: "flex-end" }, children: [
2127
+ /* @__PURE__ */ jsx2(
2128
+ "textarea",
2129
+ {
2130
+ ref: inputRef,
2131
+ value: input,
2132
+ onChange: (e) => setInput(e.target.value),
2133
+ onKeyDown: (e) => {
2134
+ if (e.key === "Enter" && !e.shiftKey) {
2135
+ e.preventDefault();
2136
+ send(input);
2137
+ }
2138
+ },
2139
+ placeholder: "Type your answer\u2026",
2140
+ rows: 1,
2141
+ disabled: busy,
2142
+ autoFocus: true,
2143
+ style: {
2144
+ flex: 1,
2145
+ minHeight: "42px",
2146
+ maxHeight: "120px",
2147
+ padding: "11px 12px",
2148
+ borderRadius: "10px",
2149
+ border: `1px solid ${t2.inputBorder}`,
2150
+ backgroundColor: t2.inputBg,
2151
+ color: t2.text,
2152
+ fontSize: "13px",
2153
+ lineHeight: 1.4,
2154
+ fontFamily: "inherit",
2155
+ resize: "none",
2156
+ outline: "none",
2157
+ boxSizing: "border-box"
2158
+ }
2159
+ }
2160
+ ),
2161
+ /* @__PURE__ */ jsx2(
2162
+ "button",
2163
+ {
2164
+ type: "button",
2165
+ "data-gg-sheet-send": "",
2166
+ onClick: () => send(input),
2167
+ disabled: busy || !input.trim(),
2168
+ "aria-label": "Send message",
2169
+ style: {
2170
+ flexShrink: 0,
2171
+ width: "42px",
2172
+ height: "42px",
2173
+ borderRadius: "10px",
2174
+ border: "none",
2175
+ display: "inline-flex",
2176
+ alignItems: "center",
2177
+ justifyContent: "center",
2178
+ backgroundColor: busy || !input.trim() ? t2.bgSecondary : t2.accent,
2179
+ color: busy || !input.trim() ? t2.textMuted : t2.accentText,
2180
+ cursor: busy || !input.trim() ? "default" : "pointer"
2181
+ },
2182
+ children: /* @__PURE__ */ jsx2("svg", { width: "17", height: "17", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx2(
2183
+ "path",
2184
+ {
2185
+ d: "M3 20.5L21.5 12 3 3.5V10l12 2-12 2v6.5z",
2186
+ fill: "currentColor"
2187
+ }
2188
+ ) })
2189
+ }
2190
+ )
2191
+ ] })
2192
+ }
2193
+ )
2194
+ ]
2195
+ }
2196
+ )
2197
+ }
2198
+ )
2199
+ ] }),
2200
+ document.body
1109
2201
  );
1110
2202
  }
1111
2203
  var GLITCHGRAB_SHORTCUT = "Ctrl+Shift+G";
@@ -1276,9 +2368,9 @@ function ReporterChip({
1276
2368
  t: t2
1277
2369
  }) {
1278
2370
  var _a;
1279
- const [avatarFailed, setAvatarFailed] = useState2(false);
2371
+ const [avatarFailed, setAvatarFailed] = useState3(false);
1280
2372
  const avatarUrl = (reporter == null ? void 0 : reporter.avatarUrl) || "";
1281
- useEffect2(() => {
2373
+ useEffect3(() => {
1282
2374
  setAvatarFailed(false);
1283
2375
  }, [avatarUrl]);
1284
2376
  const name = ((_a = reporter == null ? void 0 : reporter.name) == null ? void 0 : _a.trim()) || "";
@@ -1287,13 +2379,13 @@ function ReporterChip({
1287
2379
  const label = isAnonymous ? "Anonymous" : name;
1288
2380
  const title = isAnonymous ? "No reporter identity was passed to Glitchgrab \u2014 this report won't be attributed to anyone" : [name, reporter == null ? void 0 : reporter.email, reporter == null ? void 0 : reporter.role].filter(Boolean).join(" \xB7 ");
1289
2381
  const showAvatarImage = !!avatarUrl && !avatarFailed;
1290
- return /* @__PURE__ */ jsxs2(
2382
+ return /* @__PURE__ */ jsxs3(
1291
2383
  "span",
1292
2384
  {
1293
2385
  title,
1294
2386
  style: { display: "flex", alignItems: "center", gap: "6px", minWidth: 0 },
1295
2387
  children: [
1296
- /* @__PURE__ */ jsx2(
2388
+ /* @__PURE__ */ jsx3(
1297
2389
  "span",
1298
2390
  {
1299
2391
  "aria-hidden": "true",
@@ -1313,7 +2405,7 @@ function ReporterChip({
1313
2405
  color: isAnonymous ? t2.textMuted : t2.accentText,
1314
2406
  border: `1px solid ${isAnonymous ? t2.inputBorder : "transparent"}`
1315
2407
  },
1316
- children: showAvatarImage ? /* @__PURE__ */ jsx2(
2408
+ children: showAvatarImage ? /* @__PURE__ */ jsx3(
1317
2409
  "img",
1318
2410
  {
1319
2411
  src: avatarUrl,
@@ -1323,9 +2415,9 @@ function ReporterChip({
1323
2415
  onError: () => setAvatarFailed(true),
1324
2416
  style: { width: "100%", height: "100%", objectFit: "cover" }
1325
2417
  }
1326
- ) : initials ? initials : /* @__PURE__ */ jsxs2("svg", { width: "10", height: "10", viewBox: "0 0 16 16", fill: "none", children: [
1327
- /* @__PURE__ */ jsx2("circle", { cx: "8", cy: "5.5", r: "2.75", stroke: "currentColor", strokeWidth: "1.4" }),
1328
- /* @__PURE__ */ jsx2(
2418
+ ) : initials ? initials : /* @__PURE__ */ jsxs3("svg", { width: "10", height: "10", viewBox: "0 0 16 16", fill: "none", children: [
2419
+ /* @__PURE__ */ jsx3("circle", { cx: "8", cy: "5.5", r: "2.75", stroke: "currentColor", strokeWidth: "1.4" }),
2420
+ /* @__PURE__ */ jsx3(
1329
2421
  "path",
1330
2422
  {
1331
2423
  d: "M2.75 13.5c0-2.35 2.35-3.75 5.25-3.75s5.25 1.4 5.25 3.75",
@@ -1337,7 +2429,7 @@ function ReporterChip({
1337
2429
  ] })
1338
2430
  }
1339
2431
  ),
1340
- /* @__PURE__ */ jsxs2(
2432
+ /* @__PURE__ */ jsxs3(
1341
2433
  "span",
1342
2434
  {
1343
2435
  style: {
@@ -1451,6 +2543,8 @@ function ReportDialog({
1451
2543
  report,
1452
2544
  sendFeedback: sendFeedback2,
1453
2545
  enhanceText: enhanceText2,
2546
+ assist,
2547
+ assistContext = null,
1454
2548
  transcribeAudio: transcribeAudio2,
1455
2549
  types,
1456
2550
  showSeverity = true,
@@ -1459,33 +2553,39 @@ function ReportDialog({
1459
2553
  onClose,
1460
2554
  headerSlot
1461
2555
  }) {
1462
- const [isEnhancing, setIsEnhancing] = useState2(false);
1463
- const [isEnhanced, setIsEnhanced] = useState2(false);
1464
- const [originalDescription, setOriginalDescription] = useState2(
2556
+ var _a, _b;
2557
+ const [isEnhancing, setIsEnhancing] = useState3(false);
2558
+ const [assistOpen, setAssistOpen] = useState3(false);
2559
+ const [assistNotice, setAssistNotice] = useState3(null);
2560
+ const [assistUsed, setAssistUsed] = useState3(false);
2561
+ const [typeChosen, setTypeChosen] = useState3(false);
2562
+ const [duplicateIssueNumber, setDuplicateIssueNumber] = useState3(null);
2563
+ const [isEnhanced, setIsEnhanced] = useState3(false);
2564
+ const [originalDescription, setOriginalDescription] = useState3(
1465
2565
  null
1466
2566
  );
1467
- const [isListening, setIsListening] = useState2(false);
1468
- const [isTranscribing, setIsTranscribing] = useState2(false);
1469
- const [voiceError, setVoiceError] = useState2(null);
1470
- const [screenshotDragOver, setScreenshotDragOver] = useState2(false);
1471
- const [mounted, setMounted] = useState2(false);
1472
- useEffect2(() => {
2567
+ const [isListening, setIsListening] = useState3(false);
2568
+ const [isTranscribing, setIsTranscribing] = useState3(false);
2569
+ const [voiceError, setVoiceError] = useState3(null);
2570
+ const [screenshotDragOver, setScreenshotDragOver] = useState3(false);
2571
+ const [mounted, setMounted] = useState3(false);
2572
+ useEffect3(() => {
1473
2573
  setMounted(true);
1474
2574
  }, []);
1475
- const [isOpen, setIsOpen] = useState2(false);
1476
- const [description, setDescription] = useState2("");
1477
- const [isSubmitting, setIsSubmitting] = useState2(false);
1478
- const [submitted, setSubmitted] = useState2(false);
1479
- const [screenshots, setScreenshots] = useState2([]);
1480
- const [attachments, setAttachments] = useState2([]);
1481
- const [previewIndex, setPreviewIndex] = useState2(null);
1482
- const [annotatingIndex, setAnnotatingIndex] = useState2(null);
1483
- const [previewZoomed, setPreviewZoomed] = useState2(false);
1484
- const [previewNatural, setPreviewNatural] = useState2(null);
1485
- const previewScrollRef = useRef2(null);
1486
- const previewImgElRef = useRef2(null);
1487
- const panRef = useRef2(null);
1488
- const zoomAnchorRef = useRef2(null);
2575
+ const [isOpen, setIsOpen] = useState3(false);
2576
+ const [description, setDescription] = useState3("");
2577
+ const [isSubmitting, setIsSubmitting] = useState3(false);
2578
+ const [submitted, setSubmitted] = useState3(false);
2579
+ const [screenshots, setScreenshots] = useState3([]);
2580
+ const [attachments, setAttachments] = useState3([]);
2581
+ const [previewIndex, setPreviewIndex] = useState3(null);
2582
+ const [annotatingIndex, setAnnotatingIndex] = useState3(null);
2583
+ const [previewZoomed, setPreviewZoomed] = useState3(false);
2584
+ const [previewNatural, setPreviewNatural] = useState3(null);
2585
+ const previewScrollRef = useRef3(null);
2586
+ const previewImgElRef = useRef3(null);
2587
+ const panRef = useRef3(null);
2588
+ const zoomAnchorRef = useRef3(null);
1489
2589
  const resetPreviewZoom = () => {
1490
2590
  setPreviewZoomed(false);
1491
2591
  setPreviewNatural(null);
@@ -1499,20 +2599,20 @@ function ReportDialog({
1499
2599
  resetPreviewZoom();
1500
2600
  setPreviewIndex(null);
1501
2601
  };
1502
- const fileInputRef = useRef2(null);
1503
- const modalRef = useRef2(null);
1504
- const previewImgRef = useRef2(null);
1505
- const textareaRef = useRef2(null);
1506
- const recognitionRef = useRef2(null);
1507
- const voiceBaseRef = useRef2("");
1508
- const usingWebSpeechRef = useRef2(false);
1509
- const textBeforeVoiceRef = useRef2("");
1510
- const mediaRecorderRef = useRef2(null);
1511
- const streamRef = useRef2(null);
1512
- const sarvamChunksRef = useRef2([]);
1513
- const spaceTimerRef = useRef2(null);
1514
- const isPushToTalkRef = useRef2(false);
1515
- useEffect2(() => {
2602
+ const fileInputRef = useRef3(null);
2603
+ const modalRef = useRef3(null);
2604
+ const previewImgRef = useRef3(null);
2605
+ const textareaRef = useRef3(null);
2606
+ const recognitionRef = useRef3(null);
2607
+ const voiceBaseRef = useRef3("");
2608
+ const usingWebSpeechRef = useRef3(false);
2609
+ const textBeforeVoiceRef = useRef3("");
2610
+ const mediaRecorderRef = useRef3(null);
2611
+ const streamRef = useRef3(null);
2612
+ const sarvamChunksRef = useRef3([]);
2613
+ const spaceTimerRef = useRef3(null);
2614
+ const isPushToTalkRef = useRef3(false);
2615
+ useEffect3(() => {
1516
2616
  if (!isOpen) return;
1517
2617
  const HOST_LAYERS = '[role="dialog"],[role="alertdialog"],[role="menu"],[role="listbox"]';
1518
2618
  const inerted = /* @__PURE__ */ new Set();
@@ -1538,13 +2638,13 @@ function ReportDialog({
1538
2638
  inerted.forEach((el) => el.removeAttribute("inert"));
1539
2639
  };
1540
2640
  }, [isOpen]);
1541
- const [step, setStep] = useState2(1);
1542
- const [reportType, setReportType] = useState2("BUG");
1543
- const [severity, setSeverity] = useState2("medium");
1544
- const [validationError, setValidationError] = useState2(null);
1545
- const [placeholderIdx, setPlaceholderIdx] = useState2(0);
1546
- const [rating, setRating] = useState2(0);
1547
- const [hoveredStar, setHoveredStar] = useState2(0);
2641
+ const [step, setStep] = useState3(1);
2642
+ const [reportType, setReportType] = useState3("BUG");
2643
+ const [severity, setSeverity] = useState3("medium");
2644
+ const [validationError, setValidationError] = useState3(null);
2645
+ const [placeholderIdx, setPlaceholderIdx] = useState3(0);
2646
+ const [rating, setRating] = useState3(0);
2647
+ const [hoveredStar, setHoveredStar] = useState3(0);
1548
2648
  const isRating = reportType === "RATING";
1549
2649
  const submitDisabled = isSubmitting || (isRating ? rating < 1 : !description.trim());
1550
2650
  const availableTypes = types != null ? types : [
@@ -1555,8 +2655,8 @@ function ReportDialog({
1555
2655
  "SECURITY",
1556
2656
  "QUESTION"
1557
2657
  ];
1558
- const tileGridRef = useRef2(null);
1559
- useEffect2(() => {
2658
+ const tileGridRef = useRef3(null);
2659
+ useEffect3(() => {
1560
2660
  if (!isOpen || step !== 1) return;
1561
2661
  const onKey = (e) => {
1562
2662
  const el = e.target;
@@ -1567,6 +2667,7 @@ function ReportDialog({
1567
2667
  e.preventDefault();
1568
2668
  setRating(Number(e.key));
1569
2669
  setReportType("RATING");
2670
+ setTypeChosen(true);
1570
2671
  setStep(2);
1571
2672
  return;
1572
2673
  }
@@ -1578,6 +2679,7 @@ function ReportDialog({
1578
2679
  if (match) {
1579
2680
  e.preventDefault();
1580
2681
  setReportType(match);
2682
+ setTypeChosen(true);
1581
2683
  setStep(2);
1582
2684
  }
1583
2685
  };
@@ -1585,11 +2687,11 @@ function ReportDialog({
1585
2687
  return () => window.removeEventListener("keydown", onKey);
1586
2688
  }, [isOpen, step, sendFeedback2, availableTypes.join(",")]);
1587
2689
  const handleTileGridKeyDown = (e) => {
1588
- var _a, _b, _c;
2690
+ var _a2, _b2, _c;
1589
2691
  const keys = ["ArrowRight", "ArrowLeft", "ArrowDown", "ArrowUp"];
1590
2692
  if (!keys.includes(e.key)) return;
1591
2693
  const tiles = Array.from(
1592
- (_b = (_a = tileGridRef.current) == null ? void 0 : _a.querySelectorAll("button[data-gg-type]")) != null ? _b : []
2694
+ (_b2 = (_a2 = tileGridRef.current) == null ? void 0 : _a2.querySelectorAll("button[data-gg-type]")) != null ? _b2 : []
1593
2695
  );
1594
2696
  if (tiles.length === 0) return;
1595
2697
  e.preventDefault();
@@ -1631,19 +2733,22 @@ function ReportDialog({
1631
2733
  setAnnotatingIndex(null);
1632
2734
  if (availableTypes.length === 1) {
1633
2735
  setReportType(availableTypes[0]);
2736
+ setTypeChosen(true);
1634
2737
  setStep(2);
1635
2738
  }
1636
2739
  const shot = await captureScreenshot();
1637
2740
  if (shot) setScreenshots([shot]);
2741
+ if (assist && !assistUsed) setAssistOpen(true);
1638
2742
  setIsOpen(true);
1639
2743
  };
1640
- useEffect2(() => {
2744
+ useEffect3(() => {
1641
2745
  const handler = (e) => {
1642
2746
  if (isOpen) return;
1643
2747
  const detail = e.detail;
1644
2748
  if (detail == null ? void 0 : detail.description) setDescription(detail.description);
1645
2749
  if (detail == null ? void 0 : detail.type) {
1646
2750
  setReportType(detail.type);
2751
+ setTypeChosen(true);
1647
2752
  setStep(2);
1648
2753
  }
1649
2754
  handleOpen();
@@ -1651,7 +2756,7 @@ function ReportDialog({
1651
2756
  window.addEventListener("glitchgrab:open-report", handler);
1652
2757
  return () => window.removeEventListener("glitchgrab:open-report", handler);
1653
2758
  }, [isOpen, handleOpen]);
1654
- useEffect2(() => {
2759
+ useEffect3(() => {
1655
2760
  if (!isOpen) return;
1656
2761
  const handleEsc = (e) => {
1657
2762
  if (e.key === "Escape") {
@@ -1664,29 +2769,29 @@ function ReportDialog({
1664
2769
  document.addEventListener("keydown", handleEsc);
1665
2770
  return () => document.removeEventListener("keydown", handleEsc);
1666
2771
  }, [isOpen, previewIndex, previewZoomed, annotatingIndex]);
1667
- useEffect2(() => {
2772
+ useEffect3(() => {
1668
2773
  if (previewIndex === null || annotatingIndex !== null) return;
1669
2774
  const handlePointerDown = (e) => {
1670
- var _a;
1671
- if (!((_a = previewImgRef.current) == null ? void 0 : _a.contains(e.target))) {
2775
+ var _a2;
2776
+ if (!((_a2 = previewImgRef.current) == null ? void 0 : _a2.contains(e.target))) {
1672
2777
  closePreview();
1673
2778
  }
1674
2779
  };
1675
2780
  document.addEventListener("pointerdown", handlePointerDown, true);
1676
2781
  return () => document.removeEventListener("pointerdown", handlePointerDown, true);
1677
2782
  }, [previewIndex, annotatingIndex]);
1678
- useEffect2(() => {
1679
- var _a;
2783
+ useEffect3(() => {
2784
+ var _a2;
1680
2785
  const el = previewScrollRef.current;
1681
2786
  if (!previewZoomed || !el) return;
1682
- const anchor = (_a = zoomAnchorRef.current) != null ? _a : { fx: 0.5, fy: 0.5 };
2787
+ const anchor = (_a2 = zoomAnchorRef.current) != null ? _a2 : { fx: 0.5, fy: 0.5 };
1683
2788
  el.scrollLeft = anchor.fx * el.scrollWidth - el.clientWidth / 2;
1684
2789
  el.scrollTop = anchor.fy * el.scrollHeight - el.clientHeight / 2;
1685
2790
  }, [previewZoomed]);
1686
2791
  const togglePreviewZoom = (e) => {
1687
- var _a;
2792
+ var _a2;
1688
2793
  e.stopPropagation();
1689
- if ((_a = panRef.current) == null ? void 0 : _a.moved) return;
2794
+ if ((_a2 = panRef.current) == null ? void 0 : _a2.moved) return;
1690
2795
  if (!previewZoomed && !canZoomPreview) return;
1691
2796
  const img = previewImgElRef.current;
1692
2797
  if (!previewZoomed && img) {
@@ -1721,9 +2826,9 @@ function ReportDialog({
1721
2826
  el.scrollTop = start.top - dy;
1722
2827
  };
1723
2828
  const handlePanEnd = (e) => {
1724
- var _a, _b;
2829
+ var _a2, _b2;
1725
2830
  const el = previewScrollRef.current;
1726
- const moved = (_b = (_a = panRef.current) == null ? void 0 : _a.moved) != null ? _b : false;
2831
+ const moved = (_b2 = (_a2 = panRef.current) == null ? void 0 : _a2.moved) != null ? _b2 : false;
1727
2832
  try {
1728
2833
  el == null ? void 0 : el.releasePointerCapture(e.pointerId);
1729
2834
  } catch (e2) {
@@ -1737,12 +2842,12 @@ function ReportDialog({
1737
2842
  panRef.current = null;
1738
2843
  }
1739
2844
  };
1740
- useEffect2(() => {
2845
+ useEffect3(() => {
1741
2846
  if (!isOpen) return;
1742
2847
  const handlePaste = (e) => {
1743
- var _a;
2848
+ var _a2;
1744
2849
  try {
1745
- const items = (_a = e.clipboardData) == null ? void 0 : _a.items;
2850
+ const items = (_a2 = e.clipboardData) == null ? void 0 : _a2.items;
1746
2851
  if (!items) return;
1747
2852
  const pasted = [];
1748
2853
  for (let i = 0; i < items.length; i++) {
@@ -1760,7 +2865,7 @@ function ReportDialog({
1760
2865
  window.addEventListener("paste", handlePaste);
1761
2866
  return () => window.removeEventListener("paste", handlePaste);
1762
2867
  }, [isOpen]);
1763
- useEffect2(() => {
2868
+ useEffect3(() => {
1764
2869
  if (!isOpen || !transcribeAudio2) return;
1765
2870
  const id = setInterval(() => {
1766
2871
  setPlaceholderIdx((i) => (i + 1) % 2);
@@ -1768,16 +2873,16 @@ function ReportDialog({
1768
2873
  return () => clearInterval(id);
1769
2874
  }, [isOpen, transcribeAudio2]);
1770
2875
  const stopVoice = () => {
1771
- var _a, _b;
2876
+ var _a2, _b2;
1772
2877
  usingWebSpeechRef.current = false;
1773
- (_a = recognitionRef.current) == null ? void 0 : _a.stop();
2878
+ (_a2 = recognitionRef.current) == null ? void 0 : _a2.stop();
1774
2879
  recognitionRef.current = null;
1775
2880
  sarvamChunksRef.current = [];
1776
2881
  const stream = streamRef.current;
1777
2882
  streamRef.current = null;
1778
2883
  stream == null ? void 0 : stream.getTracks().forEach((t22) => t22.stop());
1779
2884
  try {
1780
- (_b = mediaRecorderRef.current) == null ? void 0 : _b.stop();
2885
+ (_b2 = mediaRecorderRef.current) == null ? void 0 : _b2.stop();
1781
2886
  } catch (e) {
1782
2887
  }
1783
2888
  mediaRecorderRef.current = null;
@@ -1785,16 +2890,28 @@ function ReportDialog({
1785
2890
  setIsTranscribing(false);
1786
2891
  };
1787
2892
  const stopListeningAndTranscribe = () => {
1788
- var _a, _b;
2893
+ var _a2, _b2;
1789
2894
  usingWebSpeechRef.current = false;
1790
- (_a = recognitionRef.current) == null ? void 0 : _a.stop();
2895
+ (_a2 = recognitionRef.current) == null ? void 0 : _a2.stop();
1791
2896
  recognitionRef.current = null;
1792
2897
  setIsListening(false);
1793
2898
  try {
1794
- (_b = mediaRecorderRef.current) == null ? void 0 : _b.stop();
2899
+ (_b2 = mediaRecorderRef.current) == null ? void 0 : _b2.stop();
1795
2900
  } catch (e) {
1796
2901
  }
1797
2902
  };
2903
+ const sheetUp = !!assist && assistOpen;
2904
+ useEffect3(() => {
2905
+ const el = modalRef.current;
2906
+ if (!el) return;
2907
+ if (sheetUp) {
2908
+ el.setAttribute("inert", "");
2909
+ el.setAttribute("aria-hidden", "true");
2910
+ } else {
2911
+ el.removeAttribute("inert");
2912
+ el.removeAttribute("aria-hidden");
2913
+ }
2914
+ }, [sheetUp, isOpen]);
1798
2915
  const handleClose = () => {
1799
2916
  stopVoice();
1800
2917
  setIsOpen(false);
@@ -1805,11 +2922,16 @@ function ReportDialog({
1805
2922
  setRating(0);
1806
2923
  setHoveredStar(0);
1807
2924
  setReportType("BUG");
2925
+ setTypeChosen(false);
2926
+ setDuplicateIssueNumber(null);
1808
2927
  setSeverity("medium");
1809
2928
  setValidationError(null);
1810
2929
  setVoiceError(null);
1811
2930
  setIsEnhanced(false);
1812
2931
  setOriginalDescription(null);
2932
+ setAssistOpen(false);
2933
+ setAssistUsed(false);
2934
+ setAssistNotice(null);
1813
2935
  };
1814
2936
  const toggleVoice = async () => {
1815
2937
  if (isListening) {
@@ -1912,7 +3034,7 @@ function ReportDialog({
1912
3034
  }
1913
3035
  };
1914
3036
  const handleSpaceDown = (e) => {
1915
- var _a;
3037
+ var _a2;
1916
3038
  if (e.code !== "Space") return;
1917
3039
  if (isListening || isPushToTalkRef.current) {
1918
3040
  e.preventDefault();
@@ -1920,7 +3042,7 @@ function ReportDialog({
1920
3042
  }
1921
3043
  if (e.repeat || !transcribeAudio2 || isTranscribing || spaceTimerRef.current)
1922
3044
  return;
1923
- const pos = (_a = e.currentTarget.selectionStart) != null ? _a : description.length;
3045
+ const pos = (_a2 = e.currentTarget.selectionStart) != null ? _a2 : description.length;
1924
3046
  spaceTimerRef.current = setTimeout(() => {
1925
3047
  spaceTimerRef.current = null;
1926
3048
  isPushToTalkRef.current = true;
@@ -1986,6 +3108,9 @@ function ReportDialog({
1986
3108
  if (showSeverity && reportType === "BUG") {
1987
3109
  metadata.severity = severity;
1988
3110
  }
3111
+ if (duplicateIssueNumber) {
3112
+ metadata.duplicateIssueNumber = String(duplicateIssueNumber);
3113
+ }
1989
3114
  const result = await report(
1990
3115
  // The RATING branch returned above, so anything reaching here is a real
1991
3116
  // ReportType — the widened tile union can't leak into the report API.
@@ -2009,9 +3134,9 @@ function ReportDialog({
2009
3134
  }
2010
3135
  };
2011
3136
  if (!mounted) return null;
2012
- return /* @__PURE__ */ jsxs2(Fragment, { children: [
2013
- isOpen && createPortal(
2014
- /* @__PURE__ */ jsx2("style", { children: `
3137
+ return /* @__PURE__ */ jsxs3(Fragment2, { children: [
3138
+ isOpen && createPortal2(
3139
+ /* @__PURE__ */ jsx3("style", { children: `
2015
3140
  @keyframes gg-pulse{0%,100%{opacity:1}50%{opacity:0.35}}
2016
3141
  @keyframes gg-b1{0%,100%{height:3px}40%{height:13px}}
2017
3142
  @keyframes gg-b2{0%,100%{height:8px}50%{height:3px}}
@@ -2047,8 +3172,8 @@ function ReportDialog({
2047
3172
  ` }),
2048
3173
  document.body
2049
3174
  ),
2050
- isOpen && createPortal(
2051
- /* @__PURE__ */ jsx2(
3175
+ isOpen && createPortal2(
3176
+ /* @__PURE__ */ jsx3(
2052
3177
  "div",
2053
3178
  {
2054
3179
  "data-glitchgrab-layer": "",
@@ -2057,7 +3182,10 @@ function ReportDialog({
2057
3182
  inset: 0,
2058
3183
  zIndex: 2147483647,
2059
3184
  pointerEvents: "auto",
2060
- display: "flex",
3185
+ // Hidden, not unmounted, while the AI sheet is in charge — the
3186
+ // dialog's state IS the report, and unmounting would drop the
3187
+ // screenshots, attachments and step the reporter is on.
3188
+ display: sheetUp ? "none" : "flex",
2061
3189
  alignItems: "center",
2062
3190
  justifyContent: "center",
2063
3191
  backgroundColor: "rgba(0,0,0,0.5)",
@@ -2068,7 +3196,7 @@ function ReportDialog({
2068
3196
  },
2069
3197
  onPointerDown: (e) => e.stopPropagation(),
2070
3198
  onFocus: (e) => e.stopPropagation(),
2071
- children: /* @__PURE__ */ jsxs2(
3199
+ children: /* @__PURE__ */ jsxs3(
2072
3200
  "div",
2073
3201
  {
2074
3202
  ref: modalRef,
@@ -2090,7 +3218,7 @@ function ReportDialog({
2090
3218
  isolation: "isolate"
2091
3219
  },
2092
3220
  children: [
2093
- /* @__PURE__ */ jsxs2(
3221
+ /* @__PURE__ */ jsxs3(
2094
3222
  "div",
2095
3223
  {
2096
3224
  style: {
@@ -2099,7 +3227,7 @@ function ReportDialog({
2099
3227
  borderBottom: `1px solid ${t2.border}`
2100
3228
  },
2101
3229
  children: [
2102
- /* @__PURE__ */ jsxs2(
3230
+ /* @__PURE__ */ jsxs3(
2103
3231
  "div",
2104
3232
  {
2105
3233
  style: {
@@ -2108,7 +3236,7 @@ function ReportDialog({
2108
3236
  alignItems: "center"
2109
3237
  },
2110
3238
  children: [
2111
- /* @__PURE__ */ jsxs2(
3239
+ /* @__PURE__ */ jsxs3(
2112
3240
  "div",
2113
3241
  {
2114
3242
  style: {
@@ -2117,7 +3245,7 @@ function ReportDialog({
2117
3245
  gap: "8px"
2118
3246
  },
2119
3247
  children: [
2120
- step > 1 && /* @__PURE__ */ jsx2(
3248
+ step > 1 && /* @__PURE__ */ jsx3(
2121
3249
  "button",
2122
3250
  {
2123
3251
  type: "button",
@@ -2131,14 +3259,14 @@ function ReportDialog({
2131
3259
  alignItems: "center"
2132
3260
  },
2133
3261
  "aria-label": "Back",
2134
- children: /* @__PURE__ */ jsx2(
3262
+ children: /* @__PURE__ */ jsx3(
2135
3263
  "svg",
2136
3264
  {
2137
3265
  width: "16",
2138
3266
  height: "16",
2139
3267
  viewBox: "0 0 16 16",
2140
3268
  fill: "none",
2141
- children: /* @__PURE__ */ jsx2(
3269
+ children: /* @__PURE__ */ jsx3(
2142
3270
  "path",
2143
3271
  {
2144
3272
  d: "M10 3L5 8L10 13",
@@ -2152,7 +3280,7 @@ function ReportDialog({
2152
3280
  )
2153
3281
  }
2154
3282
  ),
2155
- /* @__PURE__ */ jsx2(
3283
+ /* @__PURE__ */ jsx3(
2156
3284
  "span",
2157
3285
  {
2158
3286
  style: {
@@ -2166,7 +3294,7 @@ function ReportDialog({
2166
3294
  ]
2167
3295
  }
2168
3296
  ),
2169
- /* @__PURE__ */ jsxs2(
3297
+ /* @__PURE__ */ jsxs3(
2170
3298
  "div",
2171
3299
  {
2172
3300
  style: {
@@ -2175,7 +3303,7 @@ function ReportDialog({
2175
3303
  gap: "8px"
2176
3304
  },
2177
3305
  children: [
2178
- step === 1 && /* @__PURE__ */ jsx2(
3306
+ step === 1 && /* @__PURE__ */ jsx3(
2179
3307
  "span",
2180
3308
  {
2181
3309
  title: "Press this anywhere to open Glitchgrab",
@@ -2193,7 +3321,7 @@ function ReportDialog({
2193
3321
  children: getShortcutLabel()
2194
3322
  }
2195
3323
  ),
2196
- /* @__PURE__ */ jsx2(
3324
+ /* @__PURE__ */ jsx3(
2197
3325
  "button",
2198
3326
  {
2199
3327
  type: "button",
@@ -2208,7 +3336,7 @@ function ReportDialog({
2208
3336
  justifyContent: "center"
2209
3337
  },
2210
3338
  "aria-label": "Close",
2211
- children: /* @__PURE__ */ jsx2(
3339
+ children: /* @__PURE__ */ jsx3(
2212
3340
  "svg",
2213
3341
  {
2214
3342
  width: "16",
@@ -2216,7 +3344,7 @@ function ReportDialog({
2216
3344
  viewBox: "0 0 16 16",
2217
3345
  fill: "none",
2218
3346
  style: { display: "block" },
2219
- children: /* @__PURE__ */ jsx2(
3347
+ children: /* @__PURE__ */ jsx3(
2220
3348
  "path",
2221
3349
  {
2222
3350
  d: "M4 4L12 12M12 4L4 12",
@@ -2235,7 +3363,7 @@ function ReportDialog({
2235
3363
  ]
2236
3364
  }
2237
3365
  ),
2238
- /* @__PURE__ */ jsx2(
3366
+ /* @__PURE__ */ jsx3(
2239
3367
  "div",
2240
3368
  {
2241
3369
  style: {
@@ -2245,12 +3373,12 @@ function ReportDialog({
2245
3373
  gap: "0",
2246
3374
  marginTop: "12px"
2247
3375
  },
2248
- children: [1, 2].map((s, i) => /* @__PURE__ */ jsxs2(
3376
+ children: [1, 2].map((s, i) => /* @__PURE__ */ jsxs3(
2249
3377
  "div",
2250
3378
  {
2251
3379
  style: { display: "flex", alignItems: "center" },
2252
3380
  children: [
2253
- /* @__PURE__ */ jsx2(
3381
+ /* @__PURE__ */ jsx3(
2254
3382
  "div",
2255
3383
  {
2256
3384
  style: {
@@ -2262,7 +3390,7 @@ function ReportDialog({
2262
3390
  }
2263
3391
  }
2264
3392
  ),
2265
- i < 1 && /* @__PURE__ */ jsx2(
3393
+ i < 1 && /* @__PURE__ */ jsx3(
2266
3394
  "div",
2267
3395
  {
2268
3396
  style: {
@@ -2282,7 +3410,7 @@ function ReportDialog({
2282
3410
  ]
2283
3411
  }
2284
3412
  ),
2285
- /* @__PURE__ */ jsx2(
3413
+ /* @__PURE__ */ jsx3(
2286
3414
  "div",
2287
3415
  {
2288
3416
  style: {
@@ -2291,7 +3419,7 @@ function ReportDialog({
2291
3419
  flex: "1 1 auto",
2292
3420
  minHeight: 0
2293
3421
  },
2294
- children: submitted ? /* @__PURE__ */ jsxs2(
3422
+ children: submitted ? /* @__PURE__ */ jsxs3(
2295
3423
  "div",
2296
3424
  {
2297
3425
  style: {
@@ -2306,9 +3434,9 @@ function ReportDialog({
2306
3434
  " sent. Thank you!"
2307
3435
  ]
2308
3436
  }
2309
- ) : /* @__PURE__ */ jsxs2(Fragment, { children: [
2310
- step === 1 && headerSlot ? /* @__PURE__ */ jsx2("div", { style: { marginBottom: "14px" }, children: headerSlot }) : null,
2311
- step === 1 && sendFeedback2 && /* @__PURE__ */ jsxs2(
3437
+ ) : /* @__PURE__ */ jsxs3(Fragment2, { children: [
3438
+ step === 1 && headerSlot ? /* @__PURE__ */ jsx3("div", { style: { marginBottom: "14px" }, children: headerSlot }) : null,
3439
+ step === 1 && sendFeedback2 && /* @__PURE__ */ jsxs3(
2312
3440
  "div",
2313
3441
  {
2314
3442
  style: {
@@ -2325,16 +3453,16 @@ function ReportDialog({
2325
3453
  },
2326
3454
  onMouseLeave: () => setHoveredStar(0),
2327
3455
  children: [
2328
- /* @__PURE__ */ jsx2(
3456
+ /* @__PURE__ */ jsx3(
2329
3457
  "span",
2330
3458
  {
2331
3459
  style: { fontSize: "13px", fontWeight: 600, color: t2.text },
2332
3460
  children: "How are we doing?"
2333
3461
  }
2334
3462
  ),
2335
- /* @__PURE__ */ jsx2("span", { style: { display: "flex", gap: "4px" }, children: [1, 2, 3, 4, 5].map((star) => {
3463
+ /* @__PURE__ */ jsx3("span", { style: { display: "flex", gap: "4px" }, children: [1, 2, 3, 4, 5].map((star) => {
2336
3464
  const filled = star <= (hoveredStar || rating);
2337
- return /* @__PURE__ */ jsx2(
3465
+ return /* @__PURE__ */ jsx3(
2338
3466
  "button",
2339
3467
  {
2340
3468
  type: "button",
@@ -2345,6 +3473,7 @@ function ReportDialog({
2345
3473
  onClick: () => {
2346
3474
  setRating(star);
2347
3475
  setReportType("RATING");
3476
+ setTypeChosen(true);
2348
3477
  setStep(2);
2349
3478
  },
2350
3479
  style: {
@@ -2354,7 +3483,7 @@ function ReportDialog({
2354
3483
  cursor: "pointer",
2355
3484
  lineHeight: 0
2356
3485
  },
2357
- children: /* @__PURE__ */ jsx2("svg", { width: "26", height: "26", viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ jsx2(
3486
+ children: /* @__PURE__ */ jsx3("svg", { width: "26", height: "26", viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ jsx3(
2358
3487
  "path",
2359
3488
  {
2360
3489
  d: "M12 3l2.6 5.3 5.9.9-4.3 4.1 1 5.8L12 16.4 6.8 19.1l1-5.8L3.5 9.2l5.9-.9L12 3z",
@@ -2371,7 +3500,7 @@ function ReportDialog({
2371
3500
  ]
2372
3501
  }
2373
3502
  ),
2374
- step === 1 && sendFeedback2 && /* @__PURE__ */ jsxs2(
3503
+ step === 1 && sendFeedback2 && /* @__PURE__ */ jsxs3(
2375
3504
  "div",
2376
3505
  {
2377
3506
  style: {
@@ -2381,13 +3510,13 @@ function ReportDialog({
2381
3510
  marginBottom: "16px"
2382
3511
  },
2383
3512
  children: [
2384
- /* @__PURE__ */ jsx2("span", { style: { flex: 1, height: "1px", background: t2.border } }),
2385
- /* @__PURE__ */ jsx2("span", { style: { fontSize: "11px", color: t2.textMuted }, children: "or report something" }),
2386
- /* @__PURE__ */ jsx2("span", { style: { flex: 1, height: "1px", background: t2.border } })
3513
+ /* @__PURE__ */ jsx3("span", { style: { flex: 1, height: "1px", background: t2.border } }),
3514
+ /* @__PURE__ */ jsx3("span", { style: { fontSize: "11px", color: t2.textMuted }, children: "or report something" }),
3515
+ /* @__PURE__ */ jsx3("span", { style: { flex: 1, height: "1px", background: t2.border } })
2387
3516
  ]
2388
3517
  }
2389
3518
  ),
2390
- step === 1 && screenshots.length > 0 && /* @__PURE__ */ jsxs2(
3519
+ step === 1 && screenshots.length > 0 && /* @__PURE__ */ jsxs3(
2391
3520
  "div",
2392
3521
  {
2393
3522
  style: {
@@ -2401,7 +3530,7 @@ function ReportDialog({
2401
3530
  background: t2.inputBg
2402
3531
  },
2403
3532
  children: [
2404
- /* @__PURE__ */ jsx2(
3533
+ /* @__PURE__ */ jsx3(
2405
3534
  "img",
2406
3535
  {
2407
3536
  src: screenshots[0],
@@ -2416,8 +3545,8 @@ function ReportDialog({
2416
3545
  }
2417
3546
  }
2418
3547
  ),
2419
- /* @__PURE__ */ jsx2("span", { style: { fontSize: "11px", color: t2.textMuted, flex: 1 }, children: "Screenshot attached" }),
2420
- /* @__PURE__ */ jsx2(
3548
+ /* @__PURE__ */ jsx3("span", { style: { fontSize: "11px", color: t2.textMuted, flex: 1 }, children: "Screenshot attached" }),
3549
+ /* @__PURE__ */ jsx3(
2421
3550
  "button",
2422
3551
  {
2423
3552
  type: "button",
@@ -2438,7 +3567,7 @@ function ReportDialog({
2438
3567
  ]
2439
3568
  }
2440
3569
  ),
2441
- step === 1 && /* @__PURE__ */ jsx2(
3570
+ step === 1 && /* @__PURE__ */ jsx3(
2442
3571
  "div",
2443
3572
  {
2444
3573
  ref: tileGridRef,
@@ -2448,13 +3577,14 @@ function ReportDialog({
2448
3577
  gridTemplateColumns: "1fr 1fr 1fr",
2449
3578
  gap: "10px"
2450
3579
  },
2451
- children: availableTypes.map((type) => /* @__PURE__ */ jsxs2(
3580
+ children: availableTypes.map((type) => /* @__PURE__ */ jsxs3(
2452
3581
  "button",
2453
3582
  {
2454
3583
  type: "button",
2455
3584
  "data-gg-type": type,
2456
3585
  onClick: () => {
2457
3586
  setReportType(type);
3587
+ setTypeChosen(true);
2458
3588
  setStep(2);
2459
3589
  },
2460
3590
  style: {
@@ -2478,7 +3608,7 @@ function ReportDialog({
2478
3608
  },
2479
3609
  children: [
2480
3610
  getTypeIcon(type, t2.accent, 22),
2481
- /* @__PURE__ */ jsx2(
3611
+ /* @__PURE__ */ jsx3(
2482
3612
  "span",
2483
3613
  {
2484
3614
  style: {
@@ -2496,8 +3626,8 @@ function ReportDialog({
2496
3626
  ))
2497
3627
  }
2498
3628
  ),
2499
- step === 2 && /* @__PURE__ */ jsxs2(Fragment, { children: [
2500
- /* @__PURE__ */ jsxs2(
3629
+ step === 2 && /* @__PURE__ */ jsxs3(Fragment2, { children: [
3630
+ /* @__PURE__ */ jsxs3(
2501
3631
  "button",
2502
3632
  {
2503
3633
  type: "button",
@@ -2520,11 +3650,11 @@ function ReportDialog({
2520
3650
  children: [
2521
3651
  getTypeIcon(reportType, isRating ? "#f59e0b" : t2.accent, 13),
2522
3652
  getTypeLabel(reportType),
2523
- /* @__PURE__ */ jsx2("span", { style: { color: t2.textMuted, fontWeight: 400 }, children: "\xB7 change" })
3653
+ /* @__PURE__ */ jsx3("span", { style: { color: t2.textMuted, fontWeight: 400 }, children: "\xB7 change" })
2524
3654
  ]
2525
3655
  }
2526
3656
  ),
2527
- isRating && /* @__PURE__ */ jsx2(
3657
+ isRating && /* @__PURE__ */ jsx3(
2528
3658
  "div",
2529
3659
  {
2530
3660
  style: {
@@ -2535,7 +3665,7 @@ function ReportDialog({
2535
3665
  onMouseLeave: () => setHoveredStar(0),
2536
3666
  children: [1, 2, 3, 4, 5].map((star) => {
2537
3667
  const filled = star <= (hoveredStar || rating);
2538
- return /* @__PURE__ */ jsx2(
3668
+ return /* @__PURE__ */ jsx3(
2539
3669
  "button",
2540
3670
  {
2541
3671
  type: "button",
@@ -2552,7 +3682,7 @@ function ReportDialog({
2552
3682
  cursor: "pointer",
2553
3683
  lineHeight: 0
2554
3684
  },
2555
- children: /* @__PURE__ */ jsx2("svg", { width: "30", height: "30", viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ jsx2(
3685
+ children: /* @__PURE__ */ jsx3("svg", { width: "30", height: "30", viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ jsx3(
2556
3686
  "path",
2557
3687
  {
2558
3688
  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",
@@ -2568,8 +3698,48 @@ function ReportDialog({
2568
3698
  })
2569
3699
  }
2570
3700
  ),
2571
- /* @__PURE__ */ jsxs2("div", { style: { position: "relative" }, children: [
2572
- /* @__PURE__ */ jsx2(
3701
+ assist && !isRating && !assistUsed && /* @__PURE__ */ jsxs3(
3702
+ "button",
3703
+ {
3704
+ type: "button",
3705
+ onClick: () => {
3706
+ setAssistNotice(null);
3707
+ setTypeChosen(true);
3708
+ setAssistOpen(true);
3709
+ },
3710
+ style: {
3711
+ display: "inline-flex",
3712
+ alignItems: "center",
3713
+ gap: "6px",
3714
+ marginBottom: "10px",
3715
+ // 8px vertical keeps the tap target at ~32px.
3716
+ padding: "8px 10px",
3717
+ borderRadius: "6px",
3718
+ border: `1px solid ${t2.accent}`,
3719
+ background: "transparent",
3720
+ color: t2.accent,
3721
+ fontSize: "12px",
3722
+ fontWeight: 600,
3723
+ fontFamily: "inherit",
3724
+ cursor: "pointer"
3725
+ },
3726
+ title: "Answer a question or two and the assistant writes the report for you",
3727
+ children: [
3728
+ /* @__PURE__ */ jsx3("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx3(
3729
+ "path",
3730
+ {
3731
+ 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",
3732
+ stroke: t2.accent,
3733
+ strokeWidth: "1.5",
3734
+ strokeLinejoin: "round"
3735
+ }
3736
+ ) }),
3737
+ "Describe it with AI"
3738
+ ]
3739
+ }
3740
+ ),
3741
+ /* @__PURE__ */ jsxs3("div", { style: { position: "relative" }, children: [
3742
+ /* @__PURE__ */ jsx3(
2573
3743
  "textarea",
2574
3744
  {
2575
3745
  ref: textareaRef,
@@ -2610,7 +3780,7 @@ function ReportDialog({
2610
3780
  autoFocus: true
2611
3781
  }
2612
3782
  ),
2613
- (isListening || isTranscribing) && /* @__PURE__ */ jsxs2(
3783
+ (isListening || isTranscribing) && /* @__PURE__ */ jsxs3(
2614
3784
  "span",
2615
3785
  {
2616
3786
  style: {
@@ -2628,7 +3798,7 @@ function ReportDialog({
2628
3798
  zIndex: 1
2629
3799
  },
2630
3800
  children: [
2631
- /* @__PURE__ */ jsx2(
3801
+ /* @__PURE__ */ jsx3(
2632
3802
  "span",
2633
3803
  {
2634
3804
  style: {
@@ -2643,7 +3813,7 @@ function ReportDialog({
2643
3813
  }
2644
3814
  ),
2645
3815
  isTranscribing ? "Transcribing\u2026" : "REC",
2646
- isListening && !isTranscribing && /* @__PURE__ */ jsx2(
3816
+ isListening && !isTranscribing && /* @__PURE__ */ jsx3(
2647
3817
  "span",
2648
3818
  {
2649
3819
  style: {
@@ -2670,7 +3840,7 @@ function ReportDialog({
2670
3840
  dur: "0.55s",
2671
3841
  delay: "0.15s"
2672
3842
  }
2673
- ].map((b, i) => /* @__PURE__ */ jsx2(
3843
+ ].map((b, i) => /* @__PURE__ */ jsx3(
2674
3844
  "span",
2675
3845
  {
2676
3846
  style: {
@@ -2690,18 +3860,18 @@ function ReportDialog({
2690
3860
  ]
2691
3861
  }
2692
3862
  ),
2693
- enhanceText2 && /* @__PURE__ */ jsxs2(
3863
+ enhanceText2 && /* @__PURE__ */ jsxs3(
2694
3864
  "button",
2695
3865
  {
2696
3866
  type: "button",
2697
3867
  onClick: async () => {
2698
- var _a;
3868
+ var _a2;
2699
3869
  if (!description.trim() || isEnhancing) return;
2700
3870
  setIsEnhancing(true);
2701
3871
  try {
2702
3872
  const polished = await enhanceText2(
2703
3873
  description,
2704
- (_a = screenshots[0]) != null ? _a : null
3874
+ (_a2 = screenshots[0]) != null ? _a2 : null
2705
3875
  );
2706
3876
  if (polished && polished !== description) {
2707
3877
  setOriginalDescription(description);
@@ -2735,7 +3905,7 @@ function ReportDialog({
2735
3905
  },
2736
3906
  title: "Polish grammar \u2014 preserves your meaning",
2737
3907
  children: [
2738
- /* @__PURE__ */ jsx2(
3908
+ /* @__PURE__ */ jsx3(
2739
3909
  "svg",
2740
3910
  {
2741
3911
  width: "11",
@@ -2743,7 +3913,7 @@ function ReportDialog({
2743
3913
  viewBox: "0 0 24 24",
2744
3914
  fill: "none",
2745
3915
  "aria-hidden": "true",
2746
- children: /* @__PURE__ */ jsx2(
3916
+ children: /* @__PURE__ */ jsx3(
2747
3917
  "path",
2748
3918
  {
2749
3919
  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",
@@ -2758,7 +3928,7 @@ function ReportDialog({
2758
3928
  ]
2759
3929
  }
2760
3930
  ),
2761
- transcribeAudio2 && /* @__PURE__ */ jsx2(
3931
+ transcribeAudio2 && /* @__PURE__ */ jsx3(
2762
3932
  "button",
2763
3933
  {
2764
3934
  type: "button",
@@ -2784,7 +3954,7 @@ function ReportDialog({
2784
3954
  padding: 0,
2785
3955
  transition: "border-color 0.2s ease, color 0.2s ease"
2786
3956
  },
2787
- children: isListening ? /* @__PURE__ */ jsx2(
3957
+ children: isListening ? /* @__PURE__ */ jsx3(
2788
3958
  "svg",
2789
3959
  {
2790
3960
  width: "12",
@@ -2792,7 +3962,7 @@ function ReportDialog({
2792
3962
  viewBox: "0 0 24 24",
2793
3963
  fill: "currentColor",
2794
3964
  "aria-hidden": "true",
2795
- children: /* @__PURE__ */ jsx2(
3965
+ children: /* @__PURE__ */ jsx3(
2796
3966
  "rect",
2797
3967
  {
2798
3968
  x: "6",
@@ -2803,7 +3973,7 @@ function ReportDialog({
2803
3973
  }
2804
3974
  )
2805
3975
  }
2806
- ) : /* @__PURE__ */ jsxs2(
3976
+ ) : /* @__PURE__ */ jsxs3(
2807
3977
  "svg",
2808
3978
  {
2809
3979
  width: "13",
@@ -2812,7 +3982,7 @@ function ReportDialog({
2812
3982
  fill: "none",
2813
3983
  "aria-hidden": "true",
2814
3984
  children: [
2815
- /* @__PURE__ */ jsx2(
3985
+ /* @__PURE__ */ jsx3(
2816
3986
  "rect",
2817
3987
  {
2818
3988
  x: "9",
@@ -2824,7 +3994,7 @@ function ReportDialog({
2824
3994
  strokeWidth: "1.8"
2825
3995
  }
2826
3996
  ),
2827
- /* @__PURE__ */ jsx2(
3997
+ /* @__PURE__ */ jsx3(
2828
3998
  "path",
2829
3999
  {
2830
4000
  d: "M5 10a7 7 0 0014 0M12 19v3M9 22h6",
@@ -2839,7 +4009,7 @@ function ReportDialog({
2839
4009
  }
2840
4010
  )
2841
4011
  ] }),
2842
- transcribeAudio2 && !isListening && !isTranscribing && /* @__PURE__ */ jsxs2(
4012
+ transcribeAudio2 && !isListening && !isTranscribing && /* @__PURE__ */ jsxs3(
2843
4013
  "div",
2844
4014
  {
2845
4015
  style: {
@@ -2853,16 +4023,16 @@ function ReportDialog({
2853
4023
  userSelect: "none"
2854
4024
  },
2855
4025
  children: [
2856
- /* @__PURE__ */ jsxs2("svg", { width: "11", height: "11", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2857
- /* @__PURE__ */ jsx2("path", { d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z" }),
2858
- /* @__PURE__ */ jsx2("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
2859
- /* @__PURE__ */ jsx2("line", { x1: "12", x2: "12", y1: "19", y2: "22" })
4026
+ /* @__PURE__ */ jsxs3("svg", { width: "11", height: "11", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
4027
+ /* @__PURE__ */ jsx3("path", { d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z" }),
4028
+ /* @__PURE__ */ jsx3("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
4029
+ /* @__PURE__ */ jsx3("line", { x1: "12", x2: "12", y1: "19", y2: "22" })
2860
4030
  ] }),
2861
4031
  "Hold Space to speak \u2014 we'll transcribe it"
2862
4032
  ]
2863
4033
  }
2864
4034
  ),
2865
- isEnhanced && originalDescription !== null && /* @__PURE__ */ jsxs2(
4035
+ isEnhanced && originalDescription !== null && /* @__PURE__ */ jsxs3(
2866
4036
  "div",
2867
4037
  {
2868
4038
  style: {
@@ -2876,7 +4046,7 @@ function ReportDialog({
2876
4046
  border: `1px solid ${t2.accent}40`
2877
4047
  },
2878
4048
  children: [
2879
- /* @__PURE__ */ jsx2(
4049
+ /* @__PURE__ */ jsx3(
2880
4050
  "svg",
2881
4051
  {
2882
4052
  width: "12",
@@ -2884,7 +4054,7 @@ function ReportDialog({
2884
4054
  viewBox: "0 0 24 24",
2885
4055
  fill: "none",
2886
4056
  style: { flexShrink: 0 },
2887
- children: /* @__PURE__ */ jsx2(
4057
+ children: /* @__PURE__ */ jsx3(
2888
4058
  "path",
2889
4059
  {
2890
4060
  d: "M12 3l1.5 4.5L18 9l-4.5 1.5L12 15l-1.5-4.5L6 9l4.5-1.5L12 3z",
@@ -2895,7 +4065,7 @@ function ReportDialog({
2895
4065
  )
2896
4066
  }
2897
4067
  ),
2898
- /* @__PURE__ */ jsx2(
4068
+ /* @__PURE__ */ jsx3(
2899
4069
  "span",
2900
4070
  {
2901
4071
  style: {
@@ -2906,7 +4076,7 @@ function ReportDialog({
2906
4076
  children: "AI enhanced"
2907
4077
  }
2908
4078
  ),
2909
- /* @__PURE__ */ jsx2(
4079
+ /* @__PURE__ */ jsx3(
2910
4080
  "button",
2911
4081
  {
2912
4082
  type: "button",
@@ -2928,7 +4098,7 @@ function ReportDialog({
2928
4098
  children: "Keep"
2929
4099
  }
2930
4100
  ),
2931
- /* @__PURE__ */ jsx2(
4101
+ /* @__PURE__ */ jsx3(
2932
4102
  "button",
2933
4103
  {
2934
4104
  type: "button",
@@ -2954,7 +4124,7 @@ function ReportDialog({
2954
4124
  ]
2955
4125
  }
2956
4126
  ),
2957
- voiceError && /* @__PURE__ */ jsx2(
4127
+ voiceError && /* @__PURE__ */ jsx3(
2958
4128
  "p",
2959
4129
  {
2960
4130
  style: {
@@ -2966,8 +4136,21 @@ function ReportDialog({
2966
4136
  children: voiceError
2967
4137
  }
2968
4138
  ),
2969
- !isRating && /* @__PURE__ */ jsxs2("div", { style: { marginTop: "10px" }, children: [
2970
- /* @__PURE__ */ jsxs2(
4139
+ assistNotice && /* @__PURE__ */ jsx3(
4140
+ "p",
4141
+ {
4142
+ style: {
4143
+ color: t2.textMuted,
4144
+ fontSize: "12px",
4145
+ marginTop: "6px",
4146
+ marginBottom: 0,
4147
+ lineHeight: 1.5
4148
+ },
4149
+ children: assistNotice
4150
+ }
4151
+ ),
4152
+ !isRating && /* @__PURE__ */ jsxs3("div", { style: { marginTop: "10px" }, children: [
4153
+ /* @__PURE__ */ jsxs3(
2971
4154
  "span",
2972
4155
  {
2973
4156
  style: {
@@ -2983,7 +4166,7 @@ function ReportDialog({
2983
4166
  ]
2984
4167
  }
2985
4168
  ),
2986
- screenshots.length > 0 && /* @__PURE__ */ jsx2(
4169
+ screenshots.length > 0 && /* @__PURE__ */ jsx3(
2987
4170
  "div",
2988
4171
  {
2989
4172
  style: {
@@ -2992,7 +4175,7 @@ function ReportDialog({
2992
4175
  gap: "8px",
2993
4176
  marginBottom: "8px"
2994
4177
  },
2995
- children: screenshots.map((src, i) => /* @__PURE__ */ jsxs2(
4178
+ children: screenshots.map((src, i) => /* @__PURE__ */ jsxs3(
2996
4179
  "div",
2997
4180
  {
2998
4181
  style: {
@@ -3001,7 +4184,7 @@ function ReportDialog({
3001
4184
  height: "56px"
3002
4185
  },
3003
4186
  children: [
3004
- /* @__PURE__ */ jsx2(
4187
+ /* @__PURE__ */ jsx3(
3005
4188
  "img",
3006
4189
  {
3007
4190
  src,
@@ -3019,7 +4202,7 @@ function ReportDialog({
3019
4202
  }
3020
4203
  }
3021
4204
  ),
3022
- /* @__PURE__ */ jsx2(
4205
+ /* @__PURE__ */ jsx3(
3023
4206
  "button",
3024
4207
  {
3025
4208
  type: "button",
@@ -3045,14 +4228,14 @@ function ReportDialog({
3045
4228
  alignItems: "center",
3046
4229
  justifyContent: "center"
3047
4230
  },
3048
- children: /* @__PURE__ */ jsx2(
4231
+ children: /* @__PURE__ */ jsx3(
3049
4232
  "svg",
3050
4233
  {
3051
4234
  width: "8",
3052
4235
  height: "8",
3053
4236
  viewBox: "0 0 10 10",
3054
4237
  fill: "none",
3055
- children: /* @__PURE__ */ jsx2(
4238
+ children: /* @__PURE__ */ jsx3(
3056
4239
  "path",
3057
4240
  {
3058
4241
  d: "M1 1L9 9M9 1L1 9",
@@ -3065,7 +4248,7 @@ function ReportDialog({
3065
4248
  )
3066
4249
  }
3067
4250
  ),
3068
- /* @__PURE__ */ jsx2(
4251
+ /* @__PURE__ */ jsx3(
3069
4252
  "button",
3070
4253
  {
3071
4254
  type: "button",
@@ -3090,14 +4273,14 @@ function ReportDialog({
3090
4273
  justifyContent: "center",
3091
4274
  boxShadow: "0 2px 8px rgba(0,0,0,0.45)"
3092
4275
  },
3093
- children: /* @__PURE__ */ jsx2(
4276
+ children: /* @__PURE__ */ jsx3(
3094
4277
  "svg",
3095
4278
  {
3096
4279
  width: "12",
3097
4280
  height: "12",
3098
4281
  viewBox: "0 0 24 24",
3099
4282
  fill: "none",
3100
- children: /* @__PURE__ */ jsx2(
4283
+ children: /* @__PURE__ */ jsx3(
3101
4284
  "path",
3102
4285
  {
3103
4286
  d: "M12 20h9M16.5 3.5a2.12 2.12 0 013 3L7 19l-4 1 1-4L16.5 3.5z",
@@ -3117,7 +4300,7 @@ function ReportDialog({
3117
4300
  ))
3118
4301
  }
3119
4302
  ),
3120
- attachments.length > 0 && /* @__PURE__ */ jsx2(
4303
+ attachments.length > 0 && /* @__PURE__ */ jsx3(
3121
4304
  "div",
3122
4305
  {
3123
4306
  style: {
@@ -3126,7 +4309,7 @@ function ReportDialog({
3126
4309
  gap: "6px",
3127
4310
  marginBottom: "8px"
3128
4311
  },
3129
- children: attachments.map((a, i) => /* @__PURE__ */ jsxs2(
4312
+ children: attachments.map((a, i) => /* @__PURE__ */ jsxs3(
3130
4313
  "div",
3131
4314
  {
3132
4315
  style: {
@@ -3138,7 +4321,7 @@ function ReportDialog({
3138
4321
  border: `1px solid ${t2.border}`
3139
4322
  },
3140
4323
  children: [
3141
- /* @__PURE__ */ jsxs2(
4324
+ /* @__PURE__ */ jsxs3(
3142
4325
  "svg",
3143
4326
  {
3144
4327
  width: "14",
@@ -3147,7 +4330,7 @@ function ReportDialog({
3147
4330
  fill: "none",
3148
4331
  style: { flexShrink: 0, opacity: 0.6 },
3149
4332
  children: [
3150
- /* @__PURE__ */ jsx2(
4333
+ /* @__PURE__ */ jsx3(
3151
4334
  "path",
3152
4335
  {
3153
4336
  d: "M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z",
@@ -3157,7 +4340,7 @@ function ReportDialog({
3157
4340
  strokeLinejoin: "round"
3158
4341
  }
3159
4342
  ),
3160
- /* @__PURE__ */ jsx2(
4343
+ /* @__PURE__ */ jsx3(
3161
4344
  "path",
3162
4345
  {
3163
4346
  d: "M14 2v6h6",
@@ -3170,7 +4353,7 @@ function ReportDialog({
3170
4353
  ]
3171
4354
  }
3172
4355
  ),
3173
- /* @__PURE__ */ jsx2(
4356
+ /* @__PURE__ */ jsx3(
3174
4357
  "span",
3175
4358
  {
3176
4359
  style: {
@@ -3184,7 +4367,7 @@ function ReportDialog({
3184
4367
  children: a.name
3185
4368
  }
3186
4369
  ),
3187
- /* @__PURE__ */ jsxs2(
4370
+ /* @__PURE__ */ jsxs3(
3188
4371
  "span",
3189
4372
  {
3190
4373
  style: { fontSize: "10px", color: t2.textMuted },
@@ -3194,7 +4377,7 @@ function ReportDialog({
3194
4377
  ]
3195
4378
  }
3196
4379
  ),
3197
- /* @__PURE__ */ jsx2(
4380
+ /* @__PURE__ */ jsx3(
3198
4381
  "button",
3199
4382
  {
3200
4383
  type: "button",
@@ -3218,14 +4401,14 @@ function ReportDialog({
3218
4401
  justifyContent: "center",
3219
4402
  flexShrink: 0
3220
4403
  },
3221
- children: /* @__PURE__ */ jsx2(
4404
+ children: /* @__PURE__ */ jsx3(
3222
4405
  "svg",
3223
4406
  {
3224
4407
  width: "8",
3225
4408
  height: "8",
3226
4409
  viewBox: "0 0 10 10",
3227
4410
  fill: "none",
3228
- children: /* @__PURE__ */ jsx2(
4411
+ children: /* @__PURE__ */ jsx3(
3229
4412
  "path",
3230
4413
  {
3231
4414
  d: "M1 1L9 9M9 1L1 9",
@@ -3244,12 +4427,12 @@ function ReportDialog({
3244
4427
  ))
3245
4428
  }
3246
4429
  ),
3247
- /* @__PURE__ */ jsx2(
4430
+ /* @__PURE__ */ jsx3(
3248
4431
  "div",
3249
4432
  {
3250
4433
  onClick: () => {
3251
- var _a;
3252
- return (_a = fileInputRef.current) == null ? void 0 : _a.click();
4434
+ var _a2;
4435
+ return (_a2 = fileInputRef.current) == null ? void 0 : _a2.click();
3253
4436
  },
3254
4437
  onDrop: (e) => {
3255
4438
  e.preventDefault();
@@ -3270,7 +4453,7 @@ function ReportDialog({
3270
4453
  background: screenshotDragOver ? isDark ? "rgba(34,211,238,0.06)" : "rgba(8,145,178,0.04)" : "transparent",
3271
4454
  transition: "border-color 0.15s ease, background 0.15s ease"
3272
4455
  },
3273
- children: screenshots.length + attachments.length > 0 ? /* @__PURE__ */ jsx2(
4456
+ children: screenshots.length + attachments.length > 0 ? /* @__PURE__ */ jsx3(
3274
4457
  "p",
3275
4458
  {
3276
4459
  style: {
@@ -3281,8 +4464,8 @@ function ReportDialog({
3281
4464
  },
3282
4465
  children: screenshotDragOver ? "Drop to attach" : "+ Add more \xB7 Drag & drop \xB7 Paste"
3283
4466
  }
3284
- ) : /* @__PURE__ */ jsxs2(Fragment, { children: [
3285
- /* @__PURE__ */ jsxs2(
4467
+ ) : /* @__PURE__ */ jsxs3(Fragment2, { children: [
4468
+ /* @__PURE__ */ jsxs3(
3286
4469
  "svg",
3287
4470
  {
3288
4471
  width: "22",
@@ -3295,7 +4478,7 @@ function ReportDialog({
3295
4478
  opacity: 0.45
3296
4479
  },
3297
4480
  children: [
3298
- /* @__PURE__ */ jsx2(
4481
+ /* @__PURE__ */ jsx3(
3299
4482
  "rect",
3300
4483
  {
3301
4484
  x: "3",
@@ -3307,7 +4490,7 @@ function ReportDialog({
3307
4490
  strokeWidth: "1.5"
3308
4491
  }
3309
4492
  ),
3310
- /* @__PURE__ */ jsx2(
4493
+ /* @__PURE__ */ jsx3(
3311
4494
  "circle",
3312
4495
  {
3313
4496
  cx: "8.5",
@@ -3317,7 +4500,7 @@ function ReportDialog({
3317
4500
  strokeWidth: "1.5"
3318
4501
  }
3319
4502
  ),
3320
- /* @__PURE__ */ jsx2(
4503
+ /* @__PURE__ */ jsx3(
3321
4504
  "path",
3322
4505
  {
3323
4506
  d: "M21 15l-5-5L5 21",
@@ -3330,7 +4513,7 @@ function ReportDialog({
3330
4513
  ]
3331
4514
  }
3332
4515
  ),
3333
- /* @__PURE__ */ jsx2(
4516
+ /* @__PURE__ */ jsx3(
3334
4517
  "p",
3335
4518
  {
3336
4519
  style: {
@@ -3342,7 +4525,7 @@ function ReportDialog({
3342
4525
  children: screenshotDragOver ? "Drop to attach" : "Add screenshots or files"
3343
4526
  }
3344
4527
  ),
3345
- /* @__PURE__ */ jsx2(
4528
+ /* @__PURE__ */ jsx3(
3346
4529
  "p",
3347
4530
  {
3348
4531
  style: {
@@ -3357,8 +4540,8 @@ function ReportDialog({
3357
4540
  }
3358
4541
  )
3359
4542
  ] }),
3360
- showSeverity && reportType === "BUG" && /* @__PURE__ */ jsxs2("div", { style: { marginTop: "10px" }, children: [
3361
- /* @__PURE__ */ jsx2(
4543
+ showSeverity && reportType === "BUG" && /* @__PURE__ */ jsxs3("div", { style: { marginTop: "10px" }, children: [
4544
+ /* @__PURE__ */ jsx3(
3362
4545
  "span",
3363
4546
  {
3364
4547
  style: {
@@ -3370,7 +4553,7 @@ function ReportDialog({
3370
4553
  children: "Severity"
3371
4554
  }
3372
4555
  ),
3373
- /* @__PURE__ */ jsx2("div", { style: { display: "flex", gap: "6px" }, children: ["low", "medium", "high"].map((s) => /* @__PURE__ */ jsx2(
4556
+ /* @__PURE__ */ jsx3("div", { style: { display: "flex", gap: "6px" }, children: ["low", "medium", "high"].map((s) => /* @__PURE__ */ jsx3(
3374
4557
  "button",
3375
4558
  {
3376
4559
  type: "button",
@@ -3394,7 +4577,7 @@ function ReportDialog({
3394
4577
  s
3395
4578
  )) })
3396
4579
  ] }),
3397
- validationError && /* @__PURE__ */ jsx2(
4580
+ validationError && /* @__PURE__ */ jsx3(
3398
4581
  "p",
3399
4582
  {
3400
4583
  style: {
@@ -3405,7 +4588,7 @@ function ReportDialog({
3405
4588
  children: validationError
3406
4589
  }
3407
4590
  ),
3408
- /* @__PURE__ */ jsx2(
4591
+ /* @__PURE__ */ jsx3(
3409
4592
  "button",
3410
4593
  {
3411
4594
  type: "button",
@@ -3432,7 +4615,7 @@ function ReportDialog({
3432
4615
  ] })
3433
4616
  }
3434
4617
  ),
3435
- /* @__PURE__ */ jsxs2(
4618
+ /* @__PURE__ */ jsxs3(
3436
4619
  "div",
3437
4620
  {
3438
4621
  style: {
@@ -3444,8 +4627,8 @@ function ReportDialog({
3444
4627
  gap: "12px"
3445
4628
  },
3446
4629
  children: [
3447
- /* @__PURE__ */ jsx2(ReporterChip, { reporter, t: t2 }),
3448
- /* @__PURE__ */ jsx2(
4630
+ /* @__PURE__ */ jsx3(ReporterChip, { reporter, t: t2 }),
4631
+ /* @__PURE__ */ jsx3(
3449
4632
  "span",
3450
4633
  {
3451
4634
  style: {
@@ -3467,7 +4650,7 @@ function ReportDialog({
3467
4650
  ),
3468
4651
  document.body
3469
4652
  ),
3470
- /* @__PURE__ */ jsx2(
4653
+ /* @__PURE__ */ jsx3(
3471
4654
  "input",
3472
4655
  {
3473
4656
  ref: fileInputRef,
@@ -3478,8 +4661,8 @@ function ReportDialog({
3478
4661
  style: { display: "none" }
3479
4662
  }
3480
4663
  ),
3481
- isOpen && previewIndex !== null && screenshots[previewIndex] && createPortal(
3482
- /* @__PURE__ */ jsxs2(
4664
+ isOpen && previewIndex !== null && screenshots[previewIndex] && createPortal2(
4665
+ /* @__PURE__ */ jsxs3(
3483
4666
  "div",
3484
4667
  {
3485
4668
  "data-glitchgrab-layer": "",
@@ -3501,7 +4684,7 @@ function ReportDialog({
3501
4684
  },
3502
4685
  onMouseDown: (e) => e.stopPropagation(),
3503
4686
  children: [
3504
- /* @__PURE__ */ jsxs2(
4687
+ /* @__PURE__ */ jsxs3(
3505
4688
  "div",
3506
4689
  {
3507
4690
  ref: previewImgRef,
@@ -3513,7 +4696,7 @@ function ReportDialog({
3513
4696
  },
3514
4697
  onClick: (e) => e.stopPropagation(),
3515
4698
  children: [
3516
- /* @__PURE__ */ jsx2(
4699
+ /* @__PURE__ */ jsx3(
3517
4700
  "div",
3518
4701
  {
3519
4702
  ref: previewScrollRef,
@@ -3532,7 +4715,7 @@ function ReportDialog({
3532
4715
  touchAction: "none",
3533
4716
  cursor: "grab"
3534
4717
  } : { maxWidth: "100%", lineHeight: 0 },
3535
- children: /* @__PURE__ */ jsx2(
4718
+ children: /* @__PURE__ */ jsx3(
3536
4719
  "img",
3537
4720
  {
3538
4721
  ref: previewImgElRef,
@@ -3560,7 +4743,7 @@ function ReportDialog({
3560
4743
  )
3561
4744
  }
3562
4745
  ),
3563
- /* @__PURE__ */ jsxs2(
4746
+ /* @__PURE__ */ jsxs3(
3564
4747
  "button",
3565
4748
  {
3566
4749
  type: "button",
@@ -3588,7 +4771,7 @@ function ReportDialog({
3588
4771
  animation: "gg-pulse 2s ease-in-out infinite"
3589
4772
  },
3590
4773
  children: [
3591
- /* @__PURE__ */ jsx2("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx2(
4774
+ /* @__PURE__ */ jsx3("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx3(
3592
4775
  "path",
3593
4776
  {
3594
4777
  d: "M12 20h9M16.5 3.5a2.12 2.12 0 013 3L7 19l-4 1 1-4L16.5 3.5z",
@@ -3605,7 +4788,7 @@ function ReportDialog({
3605
4788
  ]
3606
4789
  }
3607
4790
  ),
3608
- /* @__PURE__ */ jsx2(
4791
+ /* @__PURE__ */ jsx3(
3609
4792
  "div",
3610
4793
  {
3611
4794
  style: {
@@ -3614,7 +4797,7 @@ function ReportDialog({
3614
4797
  alignItems: "center",
3615
4798
  gap: "12px"
3616
4799
  },
3617
- children: /* @__PURE__ */ jsx2(
4800
+ children: /* @__PURE__ */ jsx3(
3618
4801
  "span",
3619
4802
  {
3620
4803
  style: {
@@ -3635,8 +4818,8 @@ function ReportDialog({
3635
4818
  ),
3636
4819
  document.body
3637
4820
  ),
3638
- isOpen && annotatingIndex !== null && screenshots[annotatingIndex] && createPortal(
3639
- /* @__PURE__ */ jsx2(
4821
+ isOpen && annotatingIndex !== null && screenshots[annotatingIndex] && createPortal2(
4822
+ /* @__PURE__ */ jsx3(
3640
4823
  AnnotationCanvas,
3641
4824
  {
3642
4825
  imageSrc: screenshots[annotatingIndex],
@@ -3650,29 +4833,70 @@ function ReportDialog({
3650
4833
  }
3651
4834
  ),
3652
4835
  document.body
4836
+ ),
4837
+ isOpen && sheetUp && /* @__PURE__ */ jsx3(
4838
+ AssistSheet,
4839
+ {
4840
+ assist,
4841
+ theme: {
4842
+ bg: t2.bg,
4843
+ bgSecondary: t2.bgSecondary,
4844
+ border: t2.border,
4845
+ text: t2.text,
4846
+ textMuted: t2.textMuted,
4847
+ inputBg: t2.inputBg,
4848
+ inputBorder: t2.inputBorder,
4849
+ accent: t2.accent,
4850
+ accentText: t2.accentText
4851
+ },
4852
+ screenshot: (_a = screenshots[0]) != null ? _a : null,
4853
+ attachmentCount: screenshots.length + attachments.length,
4854
+ context: { ...assistContext != null ? assistContext : {}, reportType },
4855
+ reportTypeLabel: getTypeLabel(reportType),
4856
+ typePicked: typeChosen,
4857
+ currentTile: reportType,
4858
+ tiles: sendFeedback2 ? [...availableTypes, "RATING"] : availableTypes,
4859
+ onPickType: (tile) => {
4860
+ setReportType(tile);
4861
+ setTypeChosen(true);
4862
+ setStep(2);
4863
+ },
4864
+ onDuplicateChange: setDuplicateIssueNumber,
4865
+ onFinish: handleClose,
4866
+ rating,
4867
+ onRatingChange: (value) => {
4868
+ setRating(value);
4869
+ if (validationError) setValidationError(null);
4870
+ },
4871
+ projectSlot: headerSlot,
4872
+ reporterName: (_b = reporter == null ? void 0 : reporter.name) != null ? _b : null,
4873
+ description,
4874
+ onDescriptionChange: (value) => {
4875
+ setDescription(value);
4876
+ if (validationError) setValidationError(null);
4877
+ },
4878
+ severity,
4879
+ onSeverityChange: setSeverity,
4880
+ showSeverity,
4881
+ isSubmitting,
4882
+ submitted,
4883
+ onSend: () => void handleSubmit(),
4884
+ onDegrade: (message) => {
4885
+ setAssistOpen(false);
4886
+ setAssistUsed(true);
4887
+ setAssistNotice(message);
4888
+ },
4889
+ onClose: () => {
4890
+ setAssistOpen(false);
4891
+ requestAnimationFrame(() => {
4892
+ var _a2;
4893
+ return (_a2 = textareaRef.current) == null ? void 0 : _a2.focus();
4894
+ });
4895
+ }
4896
+ }
3653
4897
  )
3654
4898
  ] });
3655
4899
  }
3656
- function getTypeLabel(type) {
3657
- switch (type) {
3658
- case "RATING":
3659
- return "Rating";
3660
- case "BUG":
3661
- return "Bug Report";
3662
- case "FEATURE_REQUEST":
3663
- return "Feature Request";
3664
- case "UI_IMPROVEMENT":
3665
- return "UI Improvement";
3666
- case "PERFORMANCE":
3667
- return "Performance";
3668
- case "SECURITY":
3669
- return "Security";
3670
- case "QUESTION":
3671
- return "Question";
3672
- case "OTHER":
3673
- return "Other";
3674
- }
3675
- }
3676
4900
  function getPlaceholder(type, idx = 0, hasVoice = false) {
3677
4901
  if (type === "RATING") return "What made it good \u2014 or what let you down? (optional)";
3678
4902
  if (hasVoice && idx === 1) return "Hold Space to speak \u2014 we'll transcribe it";
@@ -3703,7 +4927,7 @@ function getTypeIcon(type, color, size = 24) {
3703
4927
  };
3704
4928
  switch (type) {
3705
4929
  case "RATING":
3706
- return /* @__PURE__ */ jsx2("svg", { ...props, children: /* @__PURE__ */ jsx2(
4930
+ return /* @__PURE__ */ jsx3("svg", { ...props, children: /* @__PURE__ */ jsx3(
3707
4931
  "path",
3708
4932
  {
3709
4933
  d: "M12 3l2.6 5.3 5.9.9-4.3 4.1 1 5.8L12 16.4 6.8 19.1l1-5.8L3.5 9.2l5.9-.9L12 3z",
@@ -3713,7 +4937,7 @@ function getTypeIcon(type, color, size = 24) {
3713
4937
  }
3714
4938
  ) });
3715
4939
  case "BUG":
3716
- return /* @__PURE__ */ jsx2("svg", { ...props, children: /* @__PURE__ */ jsx2(
4940
+ return /* @__PURE__ */ jsx3("svg", { ...props, children: /* @__PURE__ */ jsx3(
3717
4941
  "path",
3718
4942
  {
3719
4943
  d: "M8 2L6.5 3.5M16 2L17.5 3.5M3 9H7M17 9H21M12 2a5 5 0 015 5v4a5 5 0 01-10 0V7a5 5 0 015-5zM7 16l-2 3M17 16l2 3",
@@ -3723,7 +4947,7 @@ function getTypeIcon(type, color, size = 24) {
3723
4947
  }
3724
4948
  ) });
3725
4949
  case "FEATURE_REQUEST":
3726
- return /* @__PURE__ */ jsx2("svg", { ...props, children: /* @__PURE__ */ jsx2(
4950
+ return /* @__PURE__ */ jsx3("svg", { ...props, children: /* @__PURE__ */ jsx3(
3727
4951
  "path",
3728
4952
  {
3729
4953
  d: "M12 2L15.09 8.26L22 9.27L17 14.14L18.18 21.02L12 17.77L5.82 21.02L7 14.14L2 9.27L8.91 8.26L12 2z",
@@ -3733,8 +4957,8 @@ function getTypeIcon(type, color, size = 24) {
3733
4957
  }
3734
4958
  ) });
3735
4959
  case "UI_IMPROVEMENT":
3736
- return /* @__PURE__ */ jsxs2("svg", { ...props, children: [
3737
- /* @__PURE__ */ jsx2(
4960
+ return /* @__PURE__ */ jsxs3("svg", { ...props, children: [
4961
+ /* @__PURE__ */ jsx3(
3738
4962
  "rect",
3739
4963
  {
3740
4964
  x: "3",
@@ -3746,7 +4970,7 @@ function getTypeIcon(type, color, size = 24) {
3746
4970
  strokeWidth: "1.5"
3747
4971
  }
3748
4972
  ),
3749
- /* @__PURE__ */ jsx2(
4973
+ /* @__PURE__ */ jsx3(
3750
4974
  "path",
3751
4975
  {
3752
4976
  d: "M3 9h18M9 21V9",
@@ -3757,7 +4981,7 @@ function getTypeIcon(type, color, size = 24) {
3757
4981
  )
3758
4982
  ] });
3759
4983
  case "PERFORMANCE":
3760
- return /* @__PURE__ */ jsx2("svg", { ...props, children: /* @__PURE__ */ jsx2(
4984
+ return /* @__PURE__ */ jsx3("svg", { ...props, children: /* @__PURE__ */ jsx3(
3761
4985
  "path",
3762
4986
  {
3763
4987
  d: "M12 21a9 9 0 100-18 9 9 0 000 18zM12 12l4-4M12 7v.01",
@@ -3768,7 +4992,7 @@ function getTypeIcon(type, color, size = 24) {
3768
4992
  }
3769
4993
  ) });
3770
4994
  case "SECURITY":
3771
- return /* @__PURE__ */ jsx2("svg", { ...props, children: /* @__PURE__ */ jsx2(
4995
+ return /* @__PURE__ */ jsx3("svg", { ...props, children: /* @__PURE__ */ jsx3(
3772
4996
  "path",
3773
4997
  {
3774
4998
  d: "M12 3l7 3v5c0 4.5-3 8.5-7 10-4-1.5-7-5.5-7-10V6l7-3z",
@@ -3778,9 +5002,9 @@ function getTypeIcon(type, color, size = 24) {
3778
5002
  }
3779
5003
  ) });
3780
5004
  case "QUESTION":
3781
- return /* @__PURE__ */ jsxs2("svg", { ...props, children: [
3782
- /* @__PURE__ */ jsx2("circle", { cx: "12", cy: "12", r: "10", stroke: color, strokeWidth: "1.5" }),
3783
- /* @__PURE__ */ jsx2(
5005
+ return /* @__PURE__ */ jsxs3("svg", { ...props, children: [
5006
+ /* @__PURE__ */ jsx3("circle", { cx: "12", cy: "12", r: "10", stroke: color, strokeWidth: "1.5" }),
5007
+ /* @__PURE__ */ jsx3(
3784
5008
  "path",
3785
5009
  {
3786
5010
  d: "M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3M12 17h.01",
@@ -3792,7 +5016,7 @@ function getTypeIcon(type, color, size = 24) {
3792
5016
  )
3793
5017
  ] });
3794
5018
  case "OTHER":
3795
- return /* @__PURE__ */ jsx2("svg", { ...props, children: /* @__PURE__ */ jsx2(
5019
+ return /* @__PURE__ */ jsx3("svg", { ...props, children: /* @__PURE__ */ jsx3(
3796
5020
  "path",
3797
5021
  {
3798
5022
  d: "M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2v10z",
@@ -3805,8 +5029,8 @@ function getTypeIcon(type, color, size = 24) {
3805
5029
  }
3806
5030
 
3807
5031
  // src/booking-dialog.tsx
3808
- import { useCallback, useEffect as useEffect3, useMemo, useState as useState3 } from "react";
3809
- import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
5032
+ import { useCallback, useEffect as useEffect4, useMemo, useState as useState4 } from "react";
5033
+ import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
3810
5034
  var t = {
3811
5035
  bg: "#141414",
3812
5036
  surface: "#1c1c1c",
@@ -3843,23 +5067,23 @@ function BookingDialog({
3843
5067
  onClose
3844
5068
  }) {
3845
5069
  var _a;
3846
- const [step, setStep] = useState3("slots");
3847
- const [slots, setSlots] = useState3(null);
3848
- const [heading, setHeading] = useState3({
5070
+ const [step, setStep] = useState4("slots");
5071
+ const [slots, setSlots] = useState4(null);
5072
+ const [heading, setHeading] = useState4({
3849
5073
  title: "Book a demo",
3850
5074
  description: null
3851
5075
  });
3852
- const [whatsappUrl, setWhatsappUrl] = useState3(null);
3853
- const [selected, setSelected] = useState3(null);
3854
- const [name, setName] = useState3("");
3855
- const [email, setEmail] = useState3("");
3856
- const [phone, setPhone] = useState3("");
3857
- const [note, setNote] = useState3("");
3858
- const [code, setCode] = useState3("");
3859
- const [bookingId, setBookingId] = useState3(null);
3860
- const [meetUrl, setMeetUrl] = useState3(null);
3861
- const [busy, setBusy] = useState3(false);
3862
- const [error, setError] = useState3(null);
5076
+ const [whatsappUrl, setWhatsappUrl] = useState4(null);
5077
+ const [selected, setSelected] = useState4(null);
5078
+ const [name, setName] = useState4("");
5079
+ const [email, setEmail] = useState4("");
5080
+ const [phone, setPhone] = useState4("");
5081
+ const [note, setNote] = useState4("");
5082
+ const [code, setCode] = useState4("");
5083
+ const [bookingId, setBookingId] = useState4(null);
5084
+ const [meetUrl, setMeetUrl] = useState4(null);
5085
+ const [busy, setBusy] = useState4(false);
5086
+ const [error, setError] = useState4(null);
3863
5087
  const headers = useMemo(
3864
5088
  () => ({ Authorization: `Bearer ${token}`, "Content-Type": "application/json" }),
3865
5089
  [token]
@@ -3889,7 +5113,7 @@ function BookingDialog({
3889
5113
  setSlots([]);
3890
5114
  }
3891
5115
  }, [baseUrl, headers]);
3892
- useEffect3(() => {
5116
+ useEffect4(() => {
3893
5117
  if (!open) return;
3894
5118
  setStep("slots");
3895
5119
  setSelected(null);
@@ -3898,7 +5122,7 @@ function BookingDialog({
3898
5122
  setError(null);
3899
5123
  void loadSlots();
3900
5124
  }, [open, loadSlots]);
3901
- useEffect3(() => {
5125
+ useEffect4(() => {
3902
5126
  if (!open) return;
3903
5127
  const onKey = (e) => {
3904
5128
  if (e.key === "Escape") onClose();
@@ -3968,7 +5192,7 @@ function BookingDialog({
3968
5192
  }
3969
5193
  }
3970
5194
  const canSubmitDetails = name.trim() && email.includes("@") && phone.replace(/\D/g, "").length >= 8;
3971
- return /* @__PURE__ */ jsx3(
5195
+ return /* @__PURE__ */ jsx4(
3972
5196
  "div",
3973
5197
  {
3974
5198
  onClick: (e) => {
@@ -3985,7 +5209,7 @@ function BookingDialog({
3985
5209
  padding: 16,
3986
5210
  fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif"
3987
5211
  },
3988
- children: /* @__PURE__ */ jsxs3(
5212
+ children: /* @__PURE__ */ jsxs4(
3989
5213
  "div",
3990
5214
  {
3991
5215
  role: "dialog",
@@ -4003,7 +5227,7 @@ function BookingDialog({
4003
5227
  overflow: "hidden"
4004
5228
  },
4005
5229
  children: [
4006
- /* @__PURE__ */ jsxs3(
5230
+ /* @__PURE__ */ jsxs4(
4007
5231
  "div",
4008
5232
  {
4009
5233
  style: {
@@ -4015,11 +5239,11 @@ function BookingDialog({
4015
5239
  gap: 12
4016
5240
  },
4017
5241
  children: [
4018
- /* @__PURE__ */ jsxs3("div", { children: [
4019
- /* @__PURE__ */ jsx3("div", { style: { fontSize: 15, fontWeight: 600 }, children: heading.title }),
4020
- heading.description && /* @__PURE__ */ jsx3("div", { style: { fontSize: 12, color: t.muted, marginTop: 2 }, children: heading.description })
5242
+ /* @__PURE__ */ jsxs4("div", { children: [
5243
+ /* @__PURE__ */ jsx4("div", { style: { fontSize: 15, fontWeight: 600 }, children: heading.title }),
5244
+ heading.description && /* @__PURE__ */ jsx4("div", { style: { fontSize: 12, color: t.muted, marginTop: 2 }, children: heading.description })
4021
5245
  ] }),
4022
- /* @__PURE__ */ jsx3(
5246
+ /* @__PURE__ */ jsx4(
4023
5247
  "button",
4024
5248
  {
4025
5249
  onClick: onClose,
@@ -4031,10 +5255,10 @@ function BookingDialog({
4031
5255
  ]
4032
5256
  }
4033
5257
  ),
4034
- /* @__PURE__ */ jsxs3("div", { style: { padding: 18, overflowY: "auto", flex: "1 1 auto" }, children: [
4035
- error && /* @__PURE__ */ jsx3("div", { style: { color: t.danger, fontSize: 12, marginBottom: 12, lineHeight: 1.5 }, children: error }),
4036
- step === "slots" && /* @__PURE__ */ jsxs3(Fragment2, { children: [
4037
- whatsappUrl && /* @__PURE__ */ jsxs3(
5258
+ /* @__PURE__ */ jsxs4("div", { style: { padding: 18, overflowY: "auto", flex: "1 1 auto" }, children: [
5259
+ error && /* @__PURE__ */ jsx4("div", { style: { color: t.danger, fontSize: 12, marginBottom: 12, lineHeight: 1.5 }, children: error }),
5260
+ step === "slots" && /* @__PURE__ */ jsxs4(Fragment3, { children: [
5261
+ whatsappUrl && /* @__PURE__ */ jsxs4(
4038
5262
  "a",
4039
5263
  {
4040
5264
  href: whatsappUrl,
@@ -4053,15 +5277,15 @@ function BookingDialog({
4053
5277
  },
4054
5278
  children: [
4055
5279
  "\u{1F4AC} Rather book on WhatsApp?",
4056
- /* @__PURE__ */ jsx3("span", { style: { display: "block", fontSize: 11, color: t.muted, marginTop: 2 }, children: "We'll ask the same questions in chat." })
5280
+ /* @__PURE__ */ jsx4("span", { style: { display: "block", fontSize: 11, color: t.muted, marginTop: 2 }, children: "We'll ask the same questions in chat." })
4057
5281
  ]
4058
5282
  }
4059
5283
  ),
4060
- slots === null && /* @__PURE__ */ jsx3("div", { style: { color: t.muted, fontSize: 13 }, children: "Finding times\u2026" }),
4061
- (slots == null ? void 0 : slots.length) === 0 && !error && /* @__PURE__ */ jsx3("div", { style: { color: t.muted, fontSize: 13 }, children: "No times available right now." }),
4062
- [...byDay.entries()].map(([day, daySlots]) => /* @__PURE__ */ jsxs3("div", { style: { marginBottom: 18 }, children: [
4063
- /* @__PURE__ */ jsx3("div", { style: { fontSize: 11, color: t.muted, marginBottom: 8, textTransform: "uppercase", letterSpacing: ".6px" }, children: formatDay(daySlots[0].startsAt) }),
4064
- /* @__PURE__ */ jsx3("div", { style: { display: "flex", flexWrap: "wrap", gap: 8 }, children: daySlots.map((slot) => /* @__PURE__ */ jsx3(
5284
+ slots === null && /* @__PURE__ */ jsx4("div", { style: { color: t.muted, fontSize: 13 }, children: "Finding times\u2026" }),
5285
+ (slots == null ? void 0 : slots.length) === 0 && !error && /* @__PURE__ */ jsx4("div", { style: { color: t.muted, fontSize: 13 }, children: "No times available right now." }),
5286
+ [...byDay.entries()].map(([day, daySlots]) => /* @__PURE__ */ jsxs4("div", { style: { marginBottom: 18 }, children: [
5287
+ /* @__PURE__ */ jsx4("div", { style: { fontSize: 11, color: t.muted, marginBottom: 8, textTransform: "uppercase", letterSpacing: ".6px" }, children: formatDay(daySlots[0].startsAt) }),
5288
+ /* @__PURE__ */ jsx4("div", { style: { display: "flex", flexWrap: "wrap", gap: 8 }, children: daySlots.map((slot) => /* @__PURE__ */ jsx4(
4065
5289
  "button",
4066
5290
  {
4067
5291
  onClick: () => {
@@ -4083,13 +5307,13 @@ function BookingDialog({
4083
5307
  )) })
4084
5308
  ] }, day))
4085
5309
  ] }),
4086
- step === "details" && selected && /* @__PURE__ */ jsxs3("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: [
4087
- /* @__PURE__ */ jsxs3("div", { style: { fontSize: 13, color: t.muted }, children: [
5310
+ step === "details" && selected && /* @__PURE__ */ jsxs4("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: [
5311
+ /* @__PURE__ */ jsxs4("div", { style: { fontSize: 13, color: t.muted }, children: [
4088
5312
  formatDay(selected.startsAt),
4089
5313
  " \xB7 ",
4090
5314
  formatTime(selected.startsAt),
4091
5315
  " \xB7 ",
4092
- /* @__PURE__ */ jsx3(
5316
+ /* @__PURE__ */ jsx4(
4093
5317
  "button",
4094
5318
  {
4095
5319
  onClick: () => setStep("slots"),
@@ -4098,9 +5322,9 @@ function BookingDialog({
4098
5322
  }
4099
5323
  )
4100
5324
  ] }),
4101
- /* @__PURE__ */ jsx3(Field, { label: "Your name", value: name, onChange: setName }),
4102
- /* @__PURE__ */ jsx3(Field, { label: "Email", value: email, onChange: setEmail, type: "email" }),
4103
- /* @__PURE__ */ jsx3(
5325
+ /* @__PURE__ */ jsx4(Field, { label: "Your name", value: name, onChange: setName }),
5326
+ /* @__PURE__ */ jsx4(Field, { label: "Email", value: email, onChange: setEmail, type: "email" }),
5327
+ /* @__PURE__ */ jsx4(
4104
5328
  Field,
4105
5329
  {
4106
5330
  label: "Mobile number",
@@ -4110,8 +5334,8 @@ function BookingDialog({
4110
5334
  hint: "We send a code here to confirm, then a reminder before the call."
4111
5335
  }
4112
5336
  ),
4113
- /* @__PURE__ */ jsx3(Field, { label: "Anything we should know? (optional)", value: note, onChange: setNote }),
4114
- /* @__PURE__ */ jsx3(
5337
+ /* @__PURE__ */ jsx4(Field, { label: "Anything we should know? (optional)", value: note, onChange: setNote }),
5338
+ /* @__PURE__ */ jsx4(
4115
5339
  "button",
4116
5340
  {
4117
5341
  onClick: startBooking,
@@ -4121,10 +5345,10 @@ function BookingDialog({
4121
5345
  }
4122
5346
  )
4123
5347
  ] }),
4124
- step === "code" && /* @__PURE__ */ jsxs3("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: [
4125
- /* @__PURE__ */ jsx3("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." }),
4126
- /* @__PURE__ */ jsx3(Field, { label: "Code", value: code, onChange: setCode }),
4127
- /* @__PURE__ */ jsx3(
5348
+ step === "code" && /* @__PURE__ */ jsxs4("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: [
5349
+ /* @__PURE__ */ jsx4("div", { style: { fontSize: 13, color: t.muted, lineHeight: 1.5 }, children: "We sent a 4-digit code to your phone. Your slot is held for 10 minutes." }),
5350
+ /* @__PURE__ */ jsx4(Field, { label: "Code", value: code, onChange: setCode }),
5351
+ /* @__PURE__ */ jsx4(
4128
5352
  "button",
4129
5353
  {
4130
5354
  onClick: confirmBooking,
@@ -4134,15 +5358,15 @@ function BookingDialog({
4134
5358
  }
4135
5359
  )
4136
5360
  ] }),
4137
- step === "done" && /* @__PURE__ */ jsxs3("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: [
4138
- /* @__PURE__ */ jsx3("div", { style: { fontSize: 15, fontWeight: 600 }, children: "You're booked." }),
4139
- /* @__PURE__ */ jsxs3("div", { style: { fontSize: 13, color: t.muted, lineHeight: 1.6 }, children: [
5361
+ step === "done" && /* @__PURE__ */ jsxs4("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: [
5362
+ /* @__PURE__ */ jsx4("div", { style: { fontSize: 15, fontWeight: 600 }, children: "You're booked." }),
5363
+ /* @__PURE__ */ jsxs4("div", { style: { fontSize: 13, color: t.muted, lineHeight: 1.6 }, children: [
4140
5364
  selected && `${formatDay(selected.startsAt)} at ${formatTime(selected.startsAt)}. `,
4141
5365
  "A calendar invite is on its way to ",
4142
5366
  email,
4143
5367
  ", and we'll send a WhatsApp reminder before the call."
4144
5368
  ] }),
4145
- meetUrl && /* @__PURE__ */ jsx3("a", { href: meetUrl, target: "_blank", rel: "noreferrer", style: { ...primaryStyle(false), textAlign: "center", textDecoration: "none" }, children: "Open the meeting link" })
5369
+ meetUrl && /* @__PURE__ */ jsx4("a", { href: meetUrl, target: "_blank", rel: "noreferrer", style: { ...primaryStyle(false), textAlign: "center", textDecoration: "none" }, children: "Open the meeting link" })
4146
5370
  ] })
4147
5371
  ] })
4148
5372
  ]
@@ -4171,9 +5395,9 @@ function Field({
4171
5395
  type = "text",
4172
5396
  hint
4173
5397
  }) {
4174
- return /* @__PURE__ */ jsxs3("label", { style: { display: "block", fontSize: 11, color: t.muted }, children: [
5398
+ return /* @__PURE__ */ jsxs4("label", { style: { display: "block", fontSize: 11, color: t.muted }, children: [
4175
5399
  label,
4176
- /* @__PURE__ */ jsx3(
5400
+ /* @__PURE__ */ jsx4(
4177
5401
  "input",
4178
5402
  {
4179
5403
  type,
@@ -4194,7 +5418,7 @@ function Field({
4194
5418
  }
4195
5419
  }
4196
5420
  ),
4197
- hint && /* @__PURE__ */ jsx3("div", { style: { marginTop: 4, fontSize: 10, color: t.muted }, children: hint })
5421
+ hint && /* @__PURE__ */ jsx4("div", { style: { marginTop: 4, fontSize: 10, color: t.muted }, children: hint })
4198
5422
  ] });
4199
5423
  }
4200
5424
 
@@ -4335,7 +5559,7 @@ function matchesShortcut(e) {
4335
5559
  }
4336
5560
 
4337
5561
  // src/provider.tsx
4338
- import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
5562
+ import { Fragment as Fragment4, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
4339
5563
  var DEFAULT_BASE_URL2 = "https://glitchgrab.dev";
4340
5564
  var GlitchgrabContext = createContext(null);
4341
5565
  function useGlitchgrab() {
@@ -4362,7 +5586,7 @@ function GlitchgrabProviderInner({
4362
5586
  context: appContext2,
4363
5587
  responseBodyOrigins: responseBodyOrigins2
4364
5588
  }) {
4365
- const visitedPagesRef = useRef3([]);
5589
+ const visitedPagesRef = useRef4([]);
4366
5590
  setRelease(release2);
4367
5591
  if (appContext2) setContexts(appContext2);
4368
5592
  registerCaptureConfig({
@@ -4374,12 +5598,12 @@ function GlitchgrabProviderInner({
4374
5598
  onError,
4375
5599
  onReportSent
4376
5600
  });
4377
- useEffect4(() => {
5601
+ useEffect5(() => {
4378
5602
  if (enableBreadcrumbs) {
4379
5603
  initBreadcrumbs(maxBreadcrumbs2, { responseBodyOrigins: responseBodyOrigins2 });
4380
5604
  }
4381
5605
  }, [enableBreadcrumbs, maxBreadcrumbs2, responseBodyOrigins2 == null ? void 0 : responseBodyOrigins2.join(",")]);
4382
- useEffect4(() => {
5606
+ useEffect5(() => {
4383
5607
  try {
4384
5608
  if (typeof window === "undefined") return;
4385
5609
  const trackPage = () => {
@@ -4416,7 +5640,7 @@ function GlitchgrabProviderInner({
4416
5640
  } catch (e) {
4417
5641
  }
4418
5642
  }, []);
4419
- useEffect4(() => {
5643
+ useEffect5(() => {
4420
5644
  try {
4421
5645
  if (typeof window === "undefined") return;
4422
5646
  if (process.env.NODE_ENV === "development") return;
@@ -4650,6 +5874,26 @@ function GlitchgrabProviderInner({
4650
5874
  },
4651
5875
  [token, baseUrl]
4652
5876
  );
5877
+ const assist = useCallback2(
5878
+ async (params) => {
5879
+ var _a;
5880
+ const ctx = captureContext(visitedPagesRef.current);
5881
+ return assistTurn(
5882
+ {
5883
+ ...params,
5884
+ context: {
5885
+ ...(_a = params.context) != null ? _a : {},
5886
+ url: ctx.url,
5887
+ visitedPages: ctx.visitedPages.slice(-5),
5888
+ breadcrumbs: ctx.breadcrumbs.slice(-25).map((b) => ({ type: b.type, message: b.message }))
5889
+ }
5890
+ },
5891
+ token,
5892
+ baseUrl
5893
+ );
5894
+ },
5895
+ [token, baseUrl]
5896
+ );
4653
5897
  const transcribe = useCallback2(
4654
5898
  async (blob) => {
4655
5899
  try {
@@ -4665,7 +5909,7 @@ function GlitchgrabProviderInner({
4665
5909
  window.dispatchEvent(new CustomEvent("glitchgrab:open-report", { detail: options }));
4666
5910
  }
4667
5911
  }, []);
4668
- useEffect4(() => {
5912
+ useEffect5(() => {
4669
5913
  try {
4670
5914
  if (typeof document === "undefined") return;
4671
5915
  document.documentElement.setAttribute("data-glitchgrab-sdk", "1");
@@ -4673,10 +5917,11 @@ function GlitchgrabProviderInner({
4673
5917
  } catch (e) {
4674
5918
  }
4675
5919
  }, []);
4676
- const [projectName, setProjectName] = useState4(null);
4677
- const [bookingOpen, setBookingOpen] = useState4(false);
5920
+ const [projectName, setProjectName] = useState5(null);
5921
+ const [aiAssist, setAiAssist] = useState5(false);
5922
+ const [bookingOpen, setBookingOpen] = useState5(false);
4678
5923
  const openBookingDialog = useCallback2(() => setBookingOpen(true), []);
4679
- useEffect4(() => {
5924
+ useEffect5(() => {
4680
5925
  let cancelled = false;
4681
5926
  fetch(`${baseUrl}/api/v1/sdk/project`, {
4682
5927
  headers: { Authorization: `Bearer ${token}` }
@@ -4684,13 +5929,14 @@ function GlitchgrabProviderInner({
4684
5929
  var _a;
4685
5930
  if (cancelled || !(json == null ? void 0 : json.success) || !((_a = json.data) == null ? void 0 : _a.name)) return;
4686
5931
  setProjectName(json.data.name);
5932
+ setAiAssist(json.data.aiAssist === true);
4687
5933
  }).catch(() => {
4688
5934
  });
4689
5935
  return () => {
4690
5936
  cancelled = true;
4691
5937
  };
4692
5938
  }, [baseUrl, token]);
4693
- useEffect4(() => {
5939
+ useEffect5(() => {
4694
5940
  try {
4695
5941
  if (typeof window === "undefined") return;
4696
5942
  const handleKeyDown = (e) => {
@@ -4714,11 +5960,11 @@ function GlitchgrabProviderInner({
4714
5960
  avatarUrl: typeof avatar === "string" ? avatar : null
4715
5961
  };
4716
5962
  }, [session]);
4717
- const [shortcutLabel, setShortcutLabel] = useState4(GLITCHGRAB_SHORTCUT2);
4718
- useEffect4(() => {
5963
+ const [shortcutLabel, setShortcutLabel] = useState5(GLITCHGRAB_SHORTCUT2);
5964
+ useEffect5(() => {
4719
5965
  setShortcutLabel(getShortcutLabel2());
4720
5966
  }, []);
4721
- return /* @__PURE__ */ jsxs4(
5967
+ return /* @__PURE__ */ jsxs5(
4722
5968
  GlitchgrabContext.Provider,
4723
5969
  {
4724
5970
  value: {
@@ -4738,7 +5984,7 @@ function GlitchgrabProviderInner({
4738
5984
  shortcutLabel
4739
5985
  },
4740
5986
  children: [
4741
- /* @__PURE__ */ jsx4(
5987
+ /* @__PURE__ */ jsx5(
4742
5988
  GlitchgrabErrorBoundary,
4743
5989
  {
4744
5990
  token,
@@ -4750,7 +5996,7 @@ function GlitchgrabProviderInner({
4750
5996
  children
4751
5997
  }
4752
5998
  ),
4753
- /* @__PURE__ */ jsx4(
5999
+ /* @__PURE__ */ jsx5(
4754
6000
  BookingDialog,
4755
6001
  {
4756
6002
  token,
@@ -4759,19 +6005,20 @@ function GlitchgrabProviderInner({
4759
6005
  onClose: () => setBookingOpen(false)
4760
6006
  }
4761
6007
  ),
4762
- /* @__PURE__ */ jsx4(
6008
+ /* @__PURE__ */ jsx5(
4763
6009
  ReportDialog,
4764
6010
  {
4765
6011
  report,
4766
6012
  sendFeedback: feedback,
4767
6013
  enhanceText: enhance,
6014
+ assist: aiAssist ? assist : void 0,
4768
6015
  transcribeAudio: transcribe,
4769
6016
  types,
4770
6017
  showSeverity,
4771
6018
  reporter,
4772
- headerSlot: projectName ? /* @__PURE__ */ jsxs4("div", { style: { fontSize: 11, color: "#9aa0a6" }, children: [
6019
+ headerSlot: projectName ? /* @__PURE__ */ jsxs5("div", { style: { fontSize: 11, color: "#9aa0a6" }, children: [
4773
6020
  "Reporting to ",
4774
- /* @__PURE__ */ jsx4("strong", { style: { color: "#e5e5e5" }, children: projectName })
6021
+ /* @__PURE__ */ jsx5("strong", { style: { color: "#e5e5e5" }, children: projectName })
4775
6022
  ] }) : null
4776
6023
  }
4777
6024
  )
@@ -4780,21 +6027,21 @@ function GlitchgrabProviderInner({
4780
6027
  );
4781
6028
  }
4782
6029
  function GlitchgrabProvider(props) {
4783
- if (!props.token) return /* @__PURE__ */ jsx4(Fragment3, { children: props.children });
6030
+ if (!props.token) return /* @__PURE__ */ jsx5(Fragment4, { children: props.children });
4784
6031
  const resolvedProps = {
4785
6032
  ...props,
4786
6033
  baseUrl: props.baseUrl || DEFAULT_BASE_URL2
4787
6034
  };
4788
6035
  try {
4789
- return /* @__PURE__ */ jsx4(GlitchgrabProviderInner, { ...resolvedProps });
6036
+ return /* @__PURE__ */ jsx5(GlitchgrabProviderInner, { ...resolvedProps });
4790
6037
  } catch (e) {
4791
- return /* @__PURE__ */ jsx4(Fragment3, { children: props.children });
6038
+ return /* @__PURE__ */ jsx5(Fragment4, { children: props.children });
4792
6039
  }
4793
6040
  }
4794
6041
 
4795
6042
  // src/report-button.tsx
4796
- import { useState as useState5 } from "react";
4797
- import { Fragment as Fragment4, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
6043
+ import { useState as useState6 } from "react";
6044
+ import { Fragment as Fragment5, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
4798
6045
  function useGlitchgrabSafe() {
4799
6046
  try {
4800
6047
  return useGlitchgrab();
@@ -4809,7 +6056,7 @@ function ReportButton({
4809
6056
  children
4810
6057
  }) {
4811
6058
  var _a, _b;
4812
- const [capturing, setCapturing] = useState5(false);
6059
+ const [capturing, setCapturing] = useState6(false);
4813
6060
  const glitchgrab = useGlitchgrabSafe();
4814
6061
  if (!glitchgrab) return null;
4815
6062
  const handleClick = async () => {
@@ -4818,7 +6065,7 @@ function ReportButton({
4818
6065
  setCapturing(false);
4819
6066
  };
4820
6067
  if (children) {
4821
- return /* @__PURE__ */ jsx5(Fragment4, { children: children({ onClick: handleClick, capturing }) });
6068
+ return /* @__PURE__ */ jsx6(Fragment5, { children: children({ onClick: handleClick, capturing }) });
4822
6069
  }
4823
6070
  const isTop = (_a = position == null ? void 0 : position.startsWith("top")) != null ? _a : false;
4824
6071
  const isLeft = (_b = position == null ? void 0 : position.endsWith("left")) != null ? _b : false;
@@ -4826,7 +6073,7 @@ function ReportButton({
4826
6073
  ...isLeft ? { left: "16px" } : { right: "16px" },
4827
6074
  ...isTop ? { top: "16px" } : { bottom: "16px" }
4828
6075
  };
4829
- return /* @__PURE__ */ jsxs5(
6076
+ return /* @__PURE__ */ jsxs6(
4830
6077
  "button",
4831
6078
  {
4832
6079
  type: "button",
@@ -4861,7 +6108,7 @@ function ReportButton({
4861
6108
  },
4862
6109
  "aria-label": label,
4863
6110
  children: [
4864
- /* @__PURE__ */ jsx5(
6111
+ /* @__PURE__ */ jsx6(
4865
6112
  "svg",
4866
6113
  {
4867
6114
  width: "16",
@@ -4869,7 +6116,7 @@ function ReportButton({
4869
6116
  viewBox: "0 0 16 16",
4870
6117
  fill: "none",
4871
6118
  style: { flexShrink: 0 },
4872
- children: /* @__PURE__ */ jsx5(
6119
+ children: /* @__PURE__ */ jsx6(
4873
6120
  "path",
4874
6121
  {
4875
6122
  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",
@@ -4885,15 +6132,15 @@ function ReportButton({
4885
6132
  }
4886
6133
 
4887
6134
  // src/book-demo-button.tsx
4888
- import { Fragment as Fragment5, jsx as jsx6 } from "react/jsx-runtime";
6135
+ import { Fragment as Fragment6, jsx as jsx7 } from "react/jsx-runtime";
4889
6136
  function BookDemoButton({
4890
6137
  label = "Book a demo",
4891
6138
  className,
4892
6139
  children
4893
6140
  }) {
4894
6141
  const { openBookingDialog } = useGlitchgrab();
4895
- if (children) return /* @__PURE__ */ jsx6(Fragment5, { children: children({ onClick: openBookingDialog }) });
4896
- return /* @__PURE__ */ jsx6(
6142
+ if (children) return /* @__PURE__ */ jsx7(Fragment6, { children: children({ onClick: openBookingDialog }) });
6143
+ return /* @__PURE__ */ jsx7(
4897
6144
  "button",
4898
6145
  {
4899
6146
  type: "button",
@@ -4915,7 +6162,7 @@ function BookDemoButton({
4915
6162
  }
4916
6163
 
4917
6164
  // src/feedback-button.tsx
4918
- import { Fragment as Fragment6, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
6165
+ import { Fragment as Fragment7, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
4919
6166
  function useGlitchgrabSafe2() {
4920
6167
  try {
4921
6168
  return useGlitchgrab();
@@ -4934,7 +6181,7 @@ function FeedbackButton({
4934
6181
  if (!glitchgrab) return null;
4935
6182
  const handleClick = () => glitchgrab.openFeedbackDialog();
4936
6183
  if (children) {
4937
- return /* @__PURE__ */ jsx7(Fragment6, { children: children({ onClick: handleClick }) });
6184
+ return /* @__PURE__ */ jsx8(Fragment7, { children: children({ onClick: handleClick }) });
4938
6185
  }
4939
6186
  const isTop = (_a = position == null ? void 0 : position.startsWith("top")) != null ? _a : false;
4940
6187
  const isLeft = (_b = position == null ? void 0 : position.endsWith("left")) != null ? _b : false;
@@ -4942,7 +6189,7 @@ function FeedbackButton({
4942
6189
  ...isLeft ? { left: "16px" } : { right: "16px" },
4943
6190
  ...isTop ? { top: "16px" } : { bottom: "16px" }
4944
6191
  };
4945
- return /* @__PURE__ */ jsxs6(
6192
+ return /* @__PURE__ */ jsxs7(
4946
6193
  "button",
4947
6194
  {
4948
6195
  type: "button",
@@ -4975,7 +6222,7 @@ function FeedbackButton({
4975
6222
  },
4976
6223
  "aria-label": label,
4977
6224
  children: [
4978
- /* @__PURE__ */ jsx7(
6225
+ /* @__PURE__ */ jsx8(
4979
6226
  "svg",
4980
6227
  {
4981
6228
  width: "16",
@@ -4984,7 +6231,7 @@ function FeedbackButton({
4984
6231
  fill: "none",
4985
6232
  style: { flexShrink: 0 },
4986
6233
  "aria-hidden": "true",
4987
- children: /* @__PURE__ */ jsx7(
6234
+ children: /* @__PURE__ */ jsx8(
4988
6235
  "path",
4989
6236
  {
4990
6237
  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",
@@ -5000,17 +6247,17 @@ function FeedbackButton({
5000
6247
  }
5001
6248
 
5002
6249
  // src/use-reports.ts
5003
- import { useState as useState6, useEffect as useEffect5, useCallback as useCallback3 } from "react";
6250
+ import { useState as useState7, useEffect as useEffect6, useCallback as useCallback3 } from "react";
5004
6251
  var BASE_URL = "https://glitchgrab.dev";
5005
6252
  function useGlitchgrabReports({
5006
6253
  token,
5007
6254
  userId,
5008
6255
  limit = 100
5009
6256
  }) {
5010
- const [reports, setReports] = useState6([]);
5011
- const [isLoading, setIsLoading] = useState6(true);
5012
- const [isFetching, setIsFetching] = useState6(false);
5013
- const [error, setError] = useState6(null);
6257
+ const [reports, setReports] = useState7([]);
6258
+ const [isLoading, setIsLoading] = useState7(true);
6259
+ const [isFetching, setIsFetching] = useState7(false);
6260
+ const [error, setError] = useState7(null);
5014
6261
  const fetchReports = useCallback3(async () => {
5015
6262
  var _a, _b;
5016
6263
  if (!token || !userId) {
@@ -5037,7 +6284,7 @@ function useGlitchgrabReports({
5037
6284
  setIsFetching(false);
5038
6285
  }
5039
6286
  }, [token, userId, limit]);
5040
- useEffect5(() => {
6287
+ useEffect6(() => {
5041
6288
  fetchReports();
5042
6289
  }, [fetchReports]);
5043
6290
  return { reports, isLoading, isFetching, error, refetch: fetchReports };
@@ -5074,8 +6321,8 @@ function useGlitchgrabActions({
5074
6321
  onSuccess,
5075
6322
  onError
5076
6323
  }) {
5077
- const [isPending, setIsPending] = useState6(false);
5078
- const [error, setError] = useState6(null);
6324
+ const [isPending, setIsPending] = useState7(false);
6325
+ const [error, setError] = useState7(null);
5079
6326
  const run = useCallback3(
5080
6327
  async (reportId, body) => {
5081
6328
  setIsPending(true);
@@ -5106,7 +6353,7 @@ function useGlitchgrabActions({
5106
6353
  }
5107
6354
 
5108
6355
  // src/use-feedback.ts
5109
- import { useState as useState7, useEffect as useEffect6, useCallback as useCallback4 } from "react";
6356
+ import { useState as useState8, useEffect as useEffect7, useCallback as useCallback4 } from "react";
5110
6357
  var DEFAULT_BASE_URL3 = "https://glitchgrab.dev";
5111
6358
  function buildUrl({
5112
6359
  approvedOnly,
@@ -5132,10 +6379,10 @@ async function fetchGlitchgrabFeedback(query) {
5132
6379
  }
5133
6380
  function useGlitchgrabFeedback(query) {
5134
6381
  const { token, approvedOnly, userId, minRating, limit, baseUrl } = query;
5135
- const [feedback, setFeedback] = useState7([]);
5136
- const [isLoading, setIsLoading] = useState7(true);
5137
- const [isFetching, setIsFetching] = useState7(false);
5138
- const [error, setError] = useState7(null);
6382
+ const [feedback, setFeedback] = useState8([]);
6383
+ const [isLoading, setIsLoading] = useState8(true);
6384
+ const [isFetching, setIsFetching] = useState8(false);
6385
+ const [error, setError] = useState8(null);
5139
6386
  const load = useCallback4(async () => {
5140
6387
  if (!token) {
5141
6388
  setIsLoading(false);
@@ -5160,7 +6407,7 @@ function useGlitchgrabFeedback(query) {
5160
6407
  setIsFetching(false);
5161
6408
  }
5162
6409
  }, [token, approvedOnly, userId, minRating, limit, baseUrl]);
5163
- useEffect6(() => {
6410
+ useEffect7(() => {
5164
6411
  load();
5165
6412
  }, [load]);
5166
6413
  return { feedback, isLoading, isFetching, error, refetch: load };