glitchgrab 1.36.0 → 1.37.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
@@ -1263,6 +1263,7 @@ function AssistSheet({
1263
1263
  onSeverityChange,
1264
1264
  showSeverity,
1265
1265
  onDuplicateChange,
1266
+ onConversationChange,
1266
1267
  isSubmitting,
1267
1268
  submitted,
1268
1269
  onSend,
@@ -1310,7 +1311,10 @@ function AssistSheet({
1310
1311
  onDegrade(result.degraded);
1311
1312
  return;
1312
1313
  }
1313
- if (result.conversationId) setConversationId(result.conversationId);
1314
+ if (result.conversationId) {
1315
+ setConversationId(result.conversationId);
1316
+ onConversationChange == null ? void 0 : onConversationChange(result.conversationId);
1317
+ }
1314
1318
  setDuplicate((_a = result.duplicate) != null ? _a : null);
1315
1319
  onDuplicateChange == null ? void 0 : onDuplicateChange((_c = (_b = result.duplicate) == null ? void 0 : _b.number) != null ? _c : null);
1316
1320
  if (result.solved) {
@@ -1480,20 +1484,24 @@ function AssistSheet({
1480
1484
  "button",
1481
1485
  {
1482
1486
  type: "button",
1487
+ "data-gg-write-myself": "",
1483
1488
  onClick: onClose,
1484
- "aria-label": "Close and write it myself",
1489
+ "aria-label": "Write it myself instead",
1485
1490
  style: {
1486
1491
  flexShrink: 0,
1487
- border: "none",
1492
+ border: `1px solid ${t2.inputBorder}`,
1493
+ borderRadius: "999px",
1488
1494
  background: "transparent",
1489
1495
  color: t2.textMuted,
1490
1496
  cursor: "pointer",
1491
- fontSize: narrow ? "18px" : "12px",
1497
+ fontSize: "11.5px",
1492
1498
  lineHeight: 1,
1493
1499
  fontFamily: "inherit",
1494
- padding: narrow ? "4px 6px" : "6px 4px"
1500
+ whiteSpace: "nowrap",
1501
+ // ~32px tall either way — this is the escape hatch, not a hint.
1502
+ padding: "9px 11px"
1495
1503
  },
1496
- children: narrow ? "\xD7" : "Write it myself"
1504
+ children: "Write it myself"
1497
1505
  }
1498
1506
  )
1499
1507
  ]
@@ -2051,7 +2059,7 @@ function AssistSheet({
2051
2059
  )
2052
2060
  }
2053
2061
  ),
2054
- !submitted && phase !== "type" && /* @__PURE__ */ jsx2(
2062
+ !submitted && phase !== "type" && /* @__PURE__ */ jsxs2(
2055
2063
  "div",
2056
2064
  {
2057
2065
  style: {
@@ -2061,134 +2069,157 @@ function AssistSheet({
2061
2069
  paddingBottom: narrow ? "max(12px, env(safe-area-inset-bottom))" : "12px",
2062
2070
  backgroundColor: t2.bg
2063
2071
  },
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",
2072
+ children: [
2073
+ phase === "solved" ? /* @__PURE__ */ jsx2(
2074
+ "button",
2129
2075
  {
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
- }
2076
+ type: "button",
2077
+ "data-gg-sheet-send": "",
2078
+ onClick: () => (onFinish != null ? onFinish : onClose)(),
2079
+ style: {
2080
+ width: "100%",
2081
+ padding: "12px",
2082
+ borderRadius: "10px",
2083
+ border: "none",
2084
+ backgroundColor: t2.accent,
2085
+ color: t2.accentText,
2086
+ fontSize: "14px",
2087
+ fontWeight: 700,
2088
+ fontFamily: "inherit",
2089
+ cursor: "pointer"
2138
2090
  },
2139
- placeholder: "Type your answer\u2026",
2140
- rows: 1,
2141
- disabled: busy,
2142
- autoFocus: true,
2091
+ children: "Done"
2092
+ }
2093
+ ) : phase === "rating" ? /* @__PURE__ */ jsx2(
2094
+ "button",
2095
+ {
2096
+ type: "button",
2097
+ "data-gg-sheet-send": "",
2098
+ onClick: onSend,
2099
+ disabled: isSubmitting || rating < 1,
2143
2100
  style: {
2144
- flex: 1,
2145
- minHeight: "42px",
2146
- maxHeight: "120px",
2147
- padding: "11px 12px",
2101
+ width: "100%",
2102
+ padding: "12px",
2148
2103
  borderRadius: "10px",
2149
- border: `1px solid ${t2.inputBorder}`,
2150
- backgroundColor: t2.inputBg,
2151
- color: t2.text,
2152
- fontSize: "13px",
2153
- lineHeight: 1.4,
2104
+ border: "none",
2105
+ backgroundColor: isSubmitting || rating < 1 ? t2.bgSecondary : "#f59e0b",
2106
+ color: isSubmitting || rating < 1 ? t2.textMuted : "#1a1a1a",
2107
+ fontSize: "14px",
2108
+ fontWeight: 700,
2154
2109
  fontFamily: "inherit",
2155
- resize: "none",
2156
- outline: "none",
2157
- boxSizing: "border-box"
2158
- }
2110
+ cursor: isSubmitting || rating < 1 ? "default" : "pointer"
2111
+ },
2112
+ children: isSubmitting ? "Sending\u2026" : rating < 1 ? "Pick a star first" : "Send Rating"
2159
2113
  }
2160
- ),
2161
- /* @__PURE__ */ jsx2(
2114
+ ) : phase === "draft" ? /* @__PURE__ */ jsx2(
2162
2115
  "button",
2163
2116
  {
2164
2117
  type: "button",
2165
2118
  "data-gg-sheet-send": "",
2166
- onClick: () => send(input),
2167
- disabled: busy || !input.trim(),
2168
- "aria-label": "Send message",
2119
+ onClick: onSend,
2120
+ disabled: isSubmitting || !description.trim(),
2169
2121
  style: {
2170
- flexShrink: 0,
2171
- width: "42px",
2172
- height: "42px",
2122
+ width: "100%",
2123
+ padding: "12px",
2173
2124
  borderRadius: "10px",
2174
2125
  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"
2126
+ backgroundColor: isSubmitting || !description.trim() ? t2.bgSecondary : t2.accent,
2127
+ color: isSubmitting || !description.trim() ? t2.textMuted : t2.accentText,
2128
+ fontSize: "14px",
2129
+ fontWeight: 700,
2130
+ fontFamily: "inherit",
2131
+ cursor: isSubmitting || !description.trim() ? "default" : "pointer"
2181
2132
  },
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"
2133
+ children: isSubmitting ? "Sending\u2026" : duplicate ? `Add to #${duplicate.number}` : "Send Report"
2134
+ }
2135
+ ) : /* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "8px", alignItems: "flex-end" }, children: [
2136
+ /* @__PURE__ */ jsx2(
2137
+ "textarea",
2138
+ {
2139
+ ref: inputRef,
2140
+ value: input,
2141
+ onChange: (e) => setInput(e.target.value),
2142
+ onKeyDown: (e) => {
2143
+ if (e.key === "Enter" && !e.shiftKey) {
2144
+ e.preventDefault();
2145
+ send(input);
2146
+ }
2147
+ },
2148
+ placeholder: "Type your answer\u2026",
2149
+ rows: 1,
2150
+ disabled: busy,
2151
+ autoFocus: true,
2152
+ style: {
2153
+ flex: 1,
2154
+ minHeight: "42px",
2155
+ maxHeight: "120px",
2156
+ padding: "11px 12px",
2157
+ borderRadius: "10px",
2158
+ border: `1px solid ${t2.inputBorder}`,
2159
+ backgroundColor: t2.inputBg,
2160
+ color: t2.text,
2161
+ fontSize: "13px",
2162
+ lineHeight: 1.4,
2163
+ fontFamily: "inherit",
2164
+ resize: "none",
2165
+ outline: "none",
2166
+ boxSizing: "border-box"
2187
2167
  }
2188
- ) })
2168
+ }
2169
+ ),
2170
+ /* @__PURE__ */ jsx2(
2171
+ "button",
2172
+ {
2173
+ type: "button",
2174
+ "data-gg-sheet-send": "",
2175
+ onClick: () => send(input),
2176
+ disabled: busy || !input.trim(),
2177
+ "aria-label": "Send message",
2178
+ "data-gg-send-message": "",
2179
+ style: {
2180
+ flexShrink: 0,
2181
+ width: "42px",
2182
+ height: "42px",
2183
+ borderRadius: "10px",
2184
+ border: "none",
2185
+ display: "inline-flex",
2186
+ alignItems: "center",
2187
+ justifyContent: "center",
2188
+ backgroundColor: busy || !input.trim() ? t2.bgSecondary : t2.accent,
2189
+ color: busy || !input.trim() ? t2.textMuted : t2.accentText,
2190
+ cursor: busy || !input.trim() ? "default" : "pointer"
2191
+ },
2192
+ children: /* @__PURE__ */ jsx2("svg", { width: "17", height: "17", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx2(
2193
+ "path",
2194
+ {
2195
+ d: "M3 20.5L21.5 12 3 3.5V10l12 2-12 2v6.5z",
2196
+ fill: "currentColor"
2197
+ }
2198
+ ) })
2199
+ }
2200
+ )
2201
+ ] }),
2202
+ phase === "chat" && messages.length > 0 && /* @__PURE__ */ jsx2(
2203
+ "button",
2204
+ {
2205
+ type: "button",
2206
+ "data-gg-write-myself": "",
2207
+ onClick: onClose,
2208
+ style: {
2209
+ display: "block",
2210
+ margin: "8px auto 0",
2211
+ border: "none",
2212
+ background: "transparent",
2213
+ color: t2.textMuted,
2214
+ fontSize: "11.5px",
2215
+ fontFamily: "inherit",
2216
+ padding: "6px 8px",
2217
+ cursor: "pointer"
2218
+ },
2219
+ children: "Not getting it? Fill the form yourself \u2192"
2189
2220
  }
2190
2221
  )
2191
- ] })
2222
+ ]
2192
2223
  }
2193
2224
  )
2194
2225
  ]
@@ -2560,6 +2591,7 @@ function ReportDialog({
2560
2591
  const [assistUsed, setAssistUsed] = useState3(false);
2561
2592
  const [typeChosen, setTypeChosen] = useState3(false);
2562
2593
  const [duplicateIssueNumber, setDuplicateIssueNumber] = useState3(null);
2594
+ const [aiConversationId, setAiConversationId] = useState3(null);
2563
2595
  const [isEnhanced, setIsEnhanced] = useState3(false);
2564
2596
  const [originalDescription, setOriginalDescription] = useState3(
2565
2597
  null
@@ -2612,6 +2644,10 @@ function ReportDialog({
2612
2644
  const sarvamChunksRef = useRef3([]);
2613
2645
  const spaceTimerRef = useRef3(null);
2614
2646
  const isPushToTalkRef = useRef3(false);
2647
+ const spaceEditsRef = useRef3(0);
2648
+ const descriptionRef = useRef3("");
2649
+ const lastVoiceTextRef = useRef3(null);
2650
+ const hadWebSpeechRef = useRef3(false);
2615
2651
  useEffect3(() => {
2616
2652
  if (!isOpen) return;
2617
2653
  const HOST_LAYERS = '[role="dialog"],[role="alertdialog"],[role="menu"],[role="listbox"]';
@@ -2872,6 +2908,22 @@ function ReportDialog({
2872
2908
  }, 3e3);
2873
2909
  return () => clearInterval(id);
2874
2910
  }, [isOpen, transcribeAudio2]);
2911
+ useEffect3(() => {
2912
+ descriptionRef.current = description;
2913
+ }, [description]);
2914
+ const rebaseVoiceOnUserEdits = () => {
2915
+ var _a2;
2916
+ const live = descriptionRef.current;
2917
+ const baseline = (_a2 = lastVoiceTextRef.current) != null ? _a2 : textBeforeVoiceRef.current;
2918
+ if (live === baseline) return;
2919
+ voiceBaseRef.current = live;
2920
+ textBeforeVoiceRef.current = live;
2921
+ };
2922
+ const setDescriptionFromVoice = (text) => {
2923
+ lastVoiceTextRef.current = text;
2924
+ descriptionRef.current = text;
2925
+ setDescription(text);
2926
+ };
2875
2927
  const stopVoice = () => {
2876
2928
  var _a2, _b2;
2877
2929
  usingWebSpeechRef.current = false;
@@ -2938,6 +2990,8 @@ function ReportDialog({
2938
2990
  stopListeningAndTranscribe();
2939
2991
  return;
2940
2992
  }
2993
+ lastVoiceTextRef.current = null;
2994
+ hadWebSpeechRef.current = false;
2941
2995
  const SpeechRec = typeof window !== "undefined" ? window.SpeechRecognition || window.webkitSpeechRecognition : void 0;
2942
2996
  let stream = null;
2943
2997
  try {
@@ -2952,13 +3006,14 @@ function ReportDialog({
2952
3006
  if (stream && transcribeAudio2) {
2953
3007
  streamRef.current = stream;
2954
3008
  sarvamChunksRef.current = [];
2955
- textBeforeVoiceRef.current = description;
3009
+ textBeforeVoiceRef.current = descriptionRef.current;
2956
3010
  const rec = new MediaRecorder(stream);
2957
3011
  mediaRecorderRef.current = rec;
2958
3012
  rec.ondataavailable = (e) => {
2959
3013
  if (e.data.size > 0) sarvamChunksRef.current.push(e.data);
2960
3014
  };
2961
3015
  rec.onstop = async () => {
3016
+ var _a2;
2962
3017
  stream.getTracks().forEach((t22) => t22.stop());
2963
3018
  if (streamRef.current === stream) streamRef.current = null;
2964
3019
  mediaRecorderRef.current = null;
@@ -2970,11 +3025,18 @@ function ReportDialog({
2970
3025
  const blob = new Blob(chunks, { type: rec.mimeType || "audio/webm" });
2971
3026
  const text = await transcribeAudio2(blob);
2972
3027
  if (text.trim()) {
2973
- const sep = textBeforeVoiceRef.current.trim() ? " " : "";
2974
- setDescription(textBeforeVoiceRef.current + sep + text.trim());
2975
- setValidationError(null);
2976
- setIsEnhanced(false);
2977
- setOriginalDescription(null);
3028
+ const live = descriptionRef.current;
3029
+ const baseline = (_a2 = lastVoiceTextRef.current) != null ? _a2 : textBeforeVoiceRef.current;
3030
+ const userEdited = live !== baseline;
3031
+ if (userEdited && hadWebSpeechRef.current) {
3032
+ } else {
3033
+ const base = userEdited ? live : textBeforeVoiceRef.current;
3034
+ const sep = base.trim() ? " " : "";
3035
+ setDescriptionFromVoice(base + sep + text.trim());
3036
+ setValidationError(null);
3037
+ setIsEnhanced(false);
3038
+ setOriginalDescription(null);
3039
+ }
2978
3040
  }
2979
3041
  } catch (e) {
2980
3042
  }
@@ -2985,8 +3047,9 @@ function ReportDialog({
2985
3047
  if (SpeechRec) {
2986
3048
  setVoiceError(null);
2987
3049
  usingWebSpeechRef.current = true;
2988
- voiceBaseRef.current = description;
2989
- textBeforeVoiceRef.current = description;
3050
+ hadWebSpeechRef.current = true;
3051
+ voiceBaseRef.current = descriptionRef.current;
3052
+ textBeforeVoiceRef.current = descriptionRef.current;
2990
3053
  const recognition = new SpeechRec();
2991
3054
  recognition.lang = "en-IN";
2992
3055
  recognition.interimResults = true;
@@ -3001,12 +3064,13 @@ function ReportDialog({
3001
3064
  if (event.results[i].isFinal) finalText += text;
3002
3065
  else interimText += text;
3003
3066
  }
3067
+ rebaseVoiceOnUserEdits();
3004
3068
  if (finalText) {
3005
3069
  const sep = voiceBaseRef.current.trim() ? " " : "";
3006
3070
  voiceBaseRef.current += sep + finalText.trim();
3007
3071
  }
3008
3072
  const liveText = interimText ? voiceBaseRef.current + (voiceBaseRef.current.trim() ? " " : "") + interimText : voiceBaseRef.current;
3009
- setDescription(liveText);
3073
+ setDescriptionFromVoice(liveText);
3010
3074
  setValidationError(null);
3011
3075
  };
3012
3076
  recognition.onend = () => {
@@ -3033,37 +3097,54 @@ function ReportDialog({
3033
3097
  setIsListening(true);
3034
3098
  }
3035
3099
  };
3100
+ const cancelPushToTalkArm = () => {
3101
+ if (!spaceTimerRef.current) return;
3102
+ clearTimeout(spaceTimerRef.current);
3103
+ spaceTimerRef.current = null;
3104
+ };
3105
+ const notePushToTalkEdit = () => {
3106
+ if (!spaceTimerRef.current) return;
3107
+ spaceEditsRef.current += 1;
3108
+ if (spaceEditsRef.current > 1) cancelPushToTalkArm();
3109
+ };
3036
3110
  const handleSpaceDown = (e) => {
3037
- var _a2;
3038
- if (e.code !== "Space") return;
3111
+ if (e.code !== "Space") {
3112
+ if (!e.metaKey && !e.ctrlKey && !e.altKey) cancelPushToTalkArm();
3113
+ return;
3114
+ }
3039
3115
  if (isListening || isPushToTalkRef.current) {
3040
3116
  e.preventDefault();
3041
3117
  return;
3042
3118
  }
3043
3119
  if (e.repeat || !transcribeAudio2 || isTranscribing || spaceTimerRef.current)
3044
3120
  return;
3045
- const pos = (_a2 = e.currentTarget.selectionStart) != null ? _a2 : description.length;
3121
+ if (e.currentTarget.value !== "") return;
3122
+ spaceEditsRef.current = 0;
3046
3123
  spaceTimerRef.current = setTimeout(() => {
3124
+ var _a2;
3047
3125
  spaceTimerRef.current = null;
3048
3126
  isPushToTalkRef.current = true;
3049
- setDescription(
3050
- (prev) => prev[pos] === " " ? prev.slice(0, pos) + prev.slice(pos + 1) : prev
3051
- );
3052
- requestAnimationFrame(() => {
3053
- if (textareaRef.current) {
3054
- textareaRef.current.selectionStart = pos;
3055
- textareaRef.current.selectionEnd = pos;
3056
- }
3057
- });
3127
+ const el = textareaRef.current;
3128
+ const caret = (_a2 = el == null ? void 0 : el.selectionStart) != null ? _a2 : null;
3129
+ if (el && caret !== null && caret === el.selectionEnd && el.value[caret - 1] === " ") {
3130
+ const cut = caret - 1;
3131
+ setDescription(
3132
+ (prev) => prev[cut] === " " ? prev.slice(0, cut) + prev.slice(cut + 1) : prev
3133
+ );
3134
+ descriptionRef.current = descriptionRef.current.slice(0, cut) + descriptionRef.current.slice(cut + 1);
3135
+ requestAnimationFrame(() => {
3136
+ if (textareaRef.current) {
3137
+ textareaRef.current.selectionStart = cut;
3138
+ textareaRef.current.selectionEnd = cut;
3139
+ }
3140
+ });
3141
+ }
3058
3142
  void toggleVoice();
3059
3143
  }, 400);
3060
3144
  };
3061
3145
  const handleSpaceUp = (e) => {
3062
3146
  if (e.code !== "Space") return;
3063
- if (spaceTimerRef.current) {
3064
- clearTimeout(spaceTimerRef.current);
3065
- spaceTimerRef.current = null;
3066
- }
3147
+ cancelPushToTalkArm();
3067
3148
  if (isPushToTalkRef.current) {
3068
3149
  isPushToTalkRef.current = false;
3069
3150
  stopListeningAndTranscribe();
@@ -3111,6 +3192,9 @@ function ReportDialog({
3111
3192
  if (duplicateIssueNumber) {
3112
3193
  metadata.duplicateIssueNumber = String(duplicateIssueNumber);
3113
3194
  }
3195
+ if (aiConversationId) {
3196
+ metadata.aiConversationId = aiConversationId;
3197
+ }
3114
3198
  const result = await report(
3115
3199
  // The RATING branch returned above, so anything reaching here is a real
3116
3200
  // ReportType — the widened tile union can't leak into the report API.
@@ -3123,6 +3207,8 @@ function ReportDialog({
3123
3207
  setDescription("");
3124
3208
  setScreenshots([]);
3125
3209
  setAttachments([]);
3210
+ setAiConversationId(null);
3211
+ setDuplicateIssueNumber(null);
3126
3212
  setTimeout(() => {
3127
3213
  setSubmitted(false);
3128
3214
  handleClose();
@@ -3745,6 +3831,7 @@ function ReportDialog({
3745
3831
  ref: textareaRef,
3746
3832
  value: description,
3747
3833
  onChange: (e) => {
3834
+ notePushToTalkEdit();
3748
3835
  setDescription(e.target.value);
3749
3836
  if (validationError) setValidationError(null);
3750
3837
  if (isEnhanced) {
@@ -4862,6 +4949,7 @@ function ReportDialog({
4862
4949
  setStep(2);
4863
4950
  },
4864
4951
  onDuplicateChange: setDuplicateIssueNumber,
4952
+ onConversationChange: setAiConversationId,
4865
4953
  onFinish: handleClose,
4866
4954
  rating,
4867
4955
  onRatingChange: (value) => {
@@ -5881,6 +5969,12 @@ function GlitchgrabProviderInner({
5881
5969
  return assistTurn(
5882
5970
  {
5883
5971
  ...params,
5972
+ // Same identity the report itself carries, from the same prop.
5973
+ reporter: session ? {
5974
+ key: session.userId,
5975
+ name: session.name ? String(session.name) : null,
5976
+ email: session.email ? String(session.email) : null
5977
+ } : void 0,
5884
5978
  context: {
5885
5979
  ...(_a = params.context) != null ? _a : {},
5886
5980
  url: ctx.url,
@@ -5892,7 +5986,7 @@ function GlitchgrabProviderInner({
5892
5986
  baseUrl
5893
5987
  );
5894
5988
  },
5895
- [token, baseUrl]
5989
+ [token, baseUrl, session]
5896
5990
  );
5897
5991
  const transcribe = useCallback2(
5898
5992
  async (blob) => {