glitchgrab 1.58.3 → 1.59.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/README.md +36 -0
- package/dist/index.d.mts +77 -1
- package/dist/index.d.ts +77 -1
- package/dist/index.js +149 -19
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +146 -19
- package/dist/index.mjs.map +1 -1
- package/dist/server.js.map +1 -1
- package/dist/server.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -371,6 +371,42 @@ function MyReports() {
|
|
|
371
371
|
}
|
|
372
372
|
```
|
|
373
373
|
|
|
374
|
+
### Show the conversation on a report
|
|
375
|
+
|
|
376
|
+
Let your user see what the team said on their report and reply — no GitHub account needed. Replies land on the GitHub issue as the Glitchgrab app, with "Commented by: <name>" underneath.
|
|
377
|
+
|
|
378
|
+
```tsx
|
|
379
|
+
import { useGlitchgrabReportThread } from "glitchgrab";
|
|
380
|
+
|
|
381
|
+
function ReportThread({ reportId }: { reportId: string }) {
|
|
382
|
+
const { report, comments, addComment, isPosting, error } = useGlitchgrabReportThread({
|
|
383
|
+
token: process.env.NEXT_PUBLIC_GLITCHGRAB_TOKEN!,
|
|
384
|
+
reportId, // from useGlitchgrabReports
|
|
385
|
+
reporterName: session.user.name, // optional, defaults to the name it was filed under
|
|
386
|
+
});
|
|
387
|
+
const [text, setText] = useState("");
|
|
388
|
+
|
|
389
|
+
return (
|
|
390
|
+
<div>
|
|
391
|
+
<h3>{report?.issue?.title} — {report?.issue?.githubState ?? "open"}</h3>
|
|
392
|
+
{comments.map((c, i) => (
|
|
393
|
+
<p key={i}><b>{c.author}</b>: {c.body}</p>
|
|
394
|
+
))}
|
|
395
|
+
<textarea value={text} onChange={(e) => setText(e.target.value)} />
|
|
396
|
+
<button
|
|
397
|
+
disabled={isPosting || !text.trim()}
|
|
398
|
+
onClick={async () => { if (await addComment(text)) setText(""); }}
|
|
399
|
+
>
|
|
400
|
+
{isPosting ? "Sending…" : "Reply"}
|
|
401
|
+
</button>
|
|
402
|
+
{error && <p>{error}</p>}
|
|
403
|
+
</div>
|
|
404
|
+
);
|
|
405
|
+
}
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
`addComment` never throws: it resolves `true` once the reply is posted and the thread reloaded, `false` with `error` set otherwise. Without the hook, use `fetchGlitchgrabReportThread` / `postGlitchgrabReportComment` (both throw) with your own data layer.
|
|
409
|
+
|
|
374
410
|
### With TanStack Query
|
|
375
411
|
|
|
376
412
|
```tsx
|
package/dist/index.d.mts
CHANGED
|
@@ -280,6 +280,82 @@ declare function useGlitchgrabActions({ token, onSuccess, onError, }: {
|
|
|
280
280
|
isPending: boolean;
|
|
281
281
|
error: string | null;
|
|
282
282
|
};
|
|
283
|
+
interface GlitchgrabComment {
|
|
284
|
+
/** GitHub login. Replies from your users post as the Glitchgrab app, with their name in the body. */
|
|
285
|
+
author: string;
|
|
286
|
+
body: string;
|
|
287
|
+
createdAt: string;
|
|
288
|
+
}
|
|
289
|
+
interface GlitchgrabReportThread {
|
|
290
|
+
id: string;
|
|
291
|
+
status: string;
|
|
292
|
+
rawInput: string | null;
|
|
293
|
+
createdAt: string;
|
|
294
|
+
issue: {
|
|
295
|
+
githubNumber: number;
|
|
296
|
+
githubUrl: string;
|
|
297
|
+
title: string;
|
|
298
|
+
body: string;
|
|
299
|
+
labels: string[];
|
|
300
|
+
severity: string | null;
|
|
301
|
+
/** "open" | "closed", or null when GitHub did not answer. */
|
|
302
|
+
githubState: string | null;
|
|
303
|
+
} | null;
|
|
304
|
+
/** Oldest first. Empty when no issue is linked yet. */
|
|
305
|
+
comments: GlitchgrabComment[];
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Fetch one report with its GitHub issue and every comment on it — the team's
|
|
309
|
+
* replies and your user's. Throws on failure; pair it with your own data layer.
|
|
310
|
+
*/
|
|
311
|
+
declare function fetchGlitchgrabReportThread({ token, reportId, }: {
|
|
312
|
+
token: string;
|
|
313
|
+
reportId: string;
|
|
314
|
+
}): Promise<GlitchgrabReportThread>;
|
|
315
|
+
/**
|
|
316
|
+
* Post a reply on the report's GitHub issue. It lands as the Glitchgrab app
|
|
317
|
+
* with "Commented by: <name>" underneath, so the team knows who said it.
|
|
318
|
+
* Throws on failure.
|
|
319
|
+
*/
|
|
320
|
+
declare function postGlitchgrabReportComment({ token, reportId, message, reporterName, reporterEmail, }: {
|
|
321
|
+
token: string;
|
|
322
|
+
reportId: string;
|
|
323
|
+
message: string;
|
|
324
|
+
/** Defaults to the name the report was filed under. */
|
|
325
|
+
reporterName?: string;
|
|
326
|
+
reporterEmail?: string;
|
|
327
|
+
}): Promise<GlitchgrabComment>;
|
|
328
|
+
/**
|
|
329
|
+
* The conversation on one report: where it stands, what the team said, and a
|
|
330
|
+
* way for your user to reply — without a GitHub account.
|
|
331
|
+
*
|
|
332
|
+
* ```tsx
|
|
333
|
+
* const { report, comments, addComment, isPosting } = useGlitchgrabReportThread({
|
|
334
|
+
* token: process.env.NEXT_PUBLIC_GLITCHGRAB_TOKEN!,
|
|
335
|
+
* reportId,
|
|
336
|
+
* reporterName: session.user.name,
|
|
337
|
+
* });
|
|
338
|
+
* ```
|
|
339
|
+
*
|
|
340
|
+
* Never throws. `addComment` resolves `true` once the reply is on the issue
|
|
341
|
+
* (and the thread has reloaded), `false` with `error` set otherwise.
|
|
342
|
+
*/
|
|
343
|
+
declare function useGlitchgrabReportThread({ token, reportId, reporterName, reporterEmail, }: {
|
|
344
|
+
token: string;
|
|
345
|
+
/** `reportId` from `useGlitchgrabReports` or the report submit result. Null waits. */
|
|
346
|
+
reportId: string | null;
|
|
347
|
+
reporterName?: string;
|
|
348
|
+
reporterEmail?: string;
|
|
349
|
+
}): {
|
|
350
|
+
report: GlitchgrabReportThread | null;
|
|
351
|
+
comments: GlitchgrabComment[];
|
|
352
|
+
isLoading: boolean;
|
|
353
|
+
isFetching: boolean;
|
|
354
|
+
isPosting: boolean;
|
|
355
|
+
error: string | null;
|
|
356
|
+
refetch: () => Promise<void>;
|
|
357
|
+
addComment: (message: string) => Promise<boolean>;
|
|
358
|
+
};
|
|
283
359
|
|
|
284
360
|
interface FeedbackQuery {
|
|
285
361
|
token: string;
|
|
@@ -422,4 +498,4 @@ declare function computeSignature(params: {
|
|
|
422
498
|
declare function shouldSkipDuplicate(signature: string, windowMs?: number, now?: number): boolean;
|
|
423
499
|
declare function clearDedupCache(): void;
|
|
424
500
|
|
|
425
|
-
export { BookDemoButton, BookingDialog, Breadcrumb, BreadcrumbType, CaptureErrorOptions, CapturedContext, DeviceInfo, FeedbackButton, FeedbackButtonProps, FeedbackPayload, type FeedbackQuery, FeedbackResult, GLITCHGRAB_SHORTCUT, GLITCHGRAB_SHORTCUT_MAC, GlitchgrabErrorBoundary, GlitchgrabFeedback, GlitchgrabProvider, GlitchgrabProviderProps, type GlitchgrabReport, GlitchgrabSession, LeadInput, LeadResult, ReportButton, ReportButtonProps, ReportPayload, ReportResult, UseGlitchgrabReturn, addBreadcrumb, captureContext, captureDeviceInfo, captureError, clearAppContext, clearBreadcrumbs, clearDedupCache, computeSignature, enhanceText, fetchGlitchgrabFeedback, fetchGlitchgrabReports, getAppContext, getBreadcrumbs, getShortcutLabel, initBreadcrumbs, matchesShortcut, sanitizeUrl, sendFeedback, sendLead, sendReport, setContext, setContexts, shouldSkipDuplicate, useGlitchgrab, useGlitchgrabActions, useGlitchgrabFeedback, useGlitchgrabReports };
|
|
501
|
+
export { BookDemoButton, BookingDialog, Breadcrumb, BreadcrumbType, CaptureErrorOptions, CapturedContext, DeviceInfo, FeedbackButton, FeedbackButtonProps, FeedbackPayload, type FeedbackQuery, FeedbackResult, GLITCHGRAB_SHORTCUT, GLITCHGRAB_SHORTCUT_MAC, type GlitchgrabComment, GlitchgrabErrorBoundary, GlitchgrabFeedback, GlitchgrabProvider, GlitchgrabProviderProps, type GlitchgrabReport, type GlitchgrabReportThread, GlitchgrabSession, LeadInput, LeadResult, ReportButton, ReportButtonProps, ReportPayload, ReportResult, UseGlitchgrabReturn, addBreadcrumb, captureContext, captureDeviceInfo, captureError, clearAppContext, clearBreadcrumbs, clearDedupCache, computeSignature, enhanceText, fetchGlitchgrabFeedback, fetchGlitchgrabReportThread, fetchGlitchgrabReports, getAppContext, getBreadcrumbs, getShortcutLabel, initBreadcrumbs, matchesShortcut, postGlitchgrabReportComment, sanitizeUrl, sendFeedback, sendLead, sendReport, setContext, setContexts, shouldSkipDuplicate, useGlitchgrab, useGlitchgrabActions, useGlitchgrabFeedback, useGlitchgrabReportThread, useGlitchgrabReports };
|
package/dist/index.d.ts
CHANGED
|
@@ -280,6 +280,82 @@ declare function useGlitchgrabActions({ token, onSuccess, onError, }: {
|
|
|
280
280
|
isPending: boolean;
|
|
281
281
|
error: string | null;
|
|
282
282
|
};
|
|
283
|
+
interface GlitchgrabComment {
|
|
284
|
+
/** GitHub login. Replies from your users post as the Glitchgrab app, with their name in the body. */
|
|
285
|
+
author: string;
|
|
286
|
+
body: string;
|
|
287
|
+
createdAt: string;
|
|
288
|
+
}
|
|
289
|
+
interface GlitchgrabReportThread {
|
|
290
|
+
id: string;
|
|
291
|
+
status: string;
|
|
292
|
+
rawInput: string | null;
|
|
293
|
+
createdAt: string;
|
|
294
|
+
issue: {
|
|
295
|
+
githubNumber: number;
|
|
296
|
+
githubUrl: string;
|
|
297
|
+
title: string;
|
|
298
|
+
body: string;
|
|
299
|
+
labels: string[];
|
|
300
|
+
severity: string | null;
|
|
301
|
+
/** "open" | "closed", or null when GitHub did not answer. */
|
|
302
|
+
githubState: string | null;
|
|
303
|
+
} | null;
|
|
304
|
+
/** Oldest first. Empty when no issue is linked yet. */
|
|
305
|
+
comments: GlitchgrabComment[];
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Fetch one report with its GitHub issue and every comment on it — the team's
|
|
309
|
+
* replies and your user's. Throws on failure; pair it with your own data layer.
|
|
310
|
+
*/
|
|
311
|
+
declare function fetchGlitchgrabReportThread({ token, reportId, }: {
|
|
312
|
+
token: string;
|
|
313
|
+
reportId: string;
|
|
314
|
+
}): Promise<GlitchgrabReportThread>;
|
|
315
|
+
/**
|
|
316
|
+
* Post a reply on the report's GitHub issue. It lands as the Glitchgrab app
|
|
317
|
+
* with "Commented by: <name>" underneath, so the team knows who said it.
|
|
318
|
+
* Throws on failure.
|
|
319
|
+
*/
|
|
320
|
+
declare function postGlitchgrabReportComment({ token, reportId, message, reporterName, reporterEmail, }: {
|
|
321
|
+
token: string;
|
|
322
|
+
reportId: string;
|
|
323
|
+
message: string;
|
|
324
|
+
/** Defaults to the name the report was filed under. */
|
|
325
|
+
reporterName?: string;
|
|
326
|
+
reporterEmail?: string;
|
|
327
|
+
}): Promise<GlitchgrabComment>;
|
|
328
|
+
/**
|
|
329
|
+
* The conversation on one report: where it stands, what the team said, and a
|
|
330
|
+
* way for your user to reply — without a GitHub account.
|
|
331
|
+
*
|
|
332
|
+
* ```tsx
|
|
333
|
+
* const { report, comments, addComment, isPosting } = useGlitchgrabReportThread({
|
|
334
|
+
* token: process.env.NEXT_PUBLIC_GLITCHGRAB_TOKEN!,
|
|
335
|
+
* reportId,
|
|
336
|
+
* reporterName: session.user.name,
|
|
337
|
+
* });
|
|
338
|
+
* ```
|
|
339
|
+
*
|
|
340
|
+
* Never throws. `addComment` resolves `true` once the reply is on the issue
|
|
341
|
+
* (and the thread has reloaded), `false` with `error` set otherwise.
|
|
342
|
+
*/
|
|
343
|
+
declare function useGlitchgrabReportThread({ token, reportId, reporterName, reporterEmail, }: {
|
|
344
|
+
token: string;
|
|
345
|
+
/** `reportId` from `useGlitchgrabReports` or the report submit result. Null waits. */
|
|
346
|
+
reportId: string | null;
|
|
347
|
+
reporterName?: string;
|
|
348
|
+
reporterEmail?: string;
|
|
349
|
+
}): {
|
|
350
|
+
report: GlitchgrabReportThread | null;
|
|
351
|
+
comments: GlitchgrabComment[];
|
|
352
|
+
isLoading: boolean;
|
|
353
|
+
isFetching: boolean;
|
|
354
|
+
isPosting: boolean;
|
|
355
|
+
error: string | null;
|
|
356
|
+
refetch: () => Promise<void>;
|
|
357
|
+
addComment: (message: string) => Promise<boolean>;
|
|
358
|
+
};
|
|
283
359
|
|
|
284
360
|
interface FeedbackQuery {
|
|
285
361
|
token: string;
|
|
@@ -422,4 +498,4 @@ declare function computeSignature(params: {
|
|
|
422
498
|
declare function shouldSkipDuplicate(signature: string, windowMs?: number, now?: number): boolean;
|
|
423
499
|
declare function clearDedupCache(): void;
|
|
424
500
|
|
|
425
|
-
export { BookDemoButton, BookingDialog, Breadcrumb, BreadcrumbType, CaptureErrorOptions, CapturedContext, DeviceInfo, FeedbackButton, FeedbackButtonProps, FeedbackPayload, type FeedbackQuery, FeedbackResult, GLITCHGRAB_SHORTCUT, GLITCHGRAB_SHORTCUT_MAC, GlitchgrabErrorBoundary, GlitchgrabFeedback, GlitchgrabProvider, GlitchgrabProviderProps, type GlitchgrabReport, GlitchgrabSession, LeadInput, LeadResult, ReportButton, ReportButtonProps, ReportPayload, ReportResult, UseGlitchgrabReturn, addBreadcrumb, captureContext, captureDeviceInfo, captureError, clearAppContext, clearBreadcrumbs, clearDedupCache, computeSignature, enhanceText, fetchGlitchgrabFeedback, fetchGlitchgrabReports, getAppContext, getBreadcrumbs, getShortcutLabel, initBreadcrumbs, matchesShortcut, sanitizeUrl, sendFeedback, sendLead, sendReport, setContext, setContexts, shouldSkipDuplicate, useGlitchgrab, useGlitchgrabActions, useGlitchgrabFeedback, useGlitchgrabReports };
|
|
501
|
+
export { BookDemoButton, BookingDialog, Breadcrumb, BreadcrumbType, CaptureErrorOptions, CapturedContext, DeviceInfo, FeedbackButton, FeedbackButtonProps, FeedbackPayload, type FeedbackQuery, FeedbackResult, GLITCHGRAB_SHORTCUT, GLITCHGRAB_SHORTCUT_MAC, type GlitchgrabComment, GlitchgrabErrorBoundary, GlitchgrabFeedback, GlitchgrabProvider, GlitchgrabProviderProps, type GlitchgrabReport, type GlitchgrabReportThread, GlitchgrabSession, LeadInput, LeadResult, ReportButton, ReportButtonProps, ReportPayload, ReportResult, UseGlitchgrabReturn, addBreadcrumb, captureContext, captureDeviceInfo, captureError, clearAppContext, clearBreadcrumbs, clearDedupCache, computeSignature, enhanceText, fetchGlitchgrabFeedback, fetchGlitchgrabReportThread, fetchGlitchgrabReports, getAppContext, getBreadcrumbs, getShortcutLabel, initBreadcrumbs, matchesShortcut, postGlitchgrabReportComment, sanitizeUrl, sendFeedback, sendLead, sendReport, setContext, setContexts, shouldSkipDuplicate, useGlitchgrab, useGlitchgrabActions, useGlitchgrabFeedback, useGlitchgrabReportThread, useGlitchgrabReports };
|
package/dist/index.js
CHANGED
|
@@ -49,12 +49,14 @@ __export(index_exports, {
|
|
|
49
49
|
computeSignature: () => computeSignature,
|
|
50
50
|
enhanceText: () => enhanceText,
|
|
51
51
|
fetchGlitchgrabFeedback: () => fetchGlitchgrabFeedback,
|
|
52
|
+
fetchGlitchgrabReportThread: () => fetchGlitchgrabReportThread,
|
|
52
53
|
fetchGlitchgrabReports: () => fetchGlitchgrabReports,
|
|
53
54
|
getAppContext: () => getAppContext,
|
|
54
55
|
getBreadcrumbs: () => getBreadcrumbs,
|
|
55
56
|
getShortcutLabel: () => getShortcutLabel2,
|
|
56
57
|
initBreadcrumbs: () => initBreadcrumbs,
|
|
57
58
|
matchesShortcut: () => matchesShortcut,
|
|
59
|
+
postGlitchgrabReportComment: () => postGlitchgrabReportComment,
|
|
58
60
|
sanitizeUrl: () => sanitizeUrl,
|
|
59
61
|
sendFeedback: () => sendFeedback,
|
|
60
62
|
sendLead: () => sendLead,
|
|
@@ -65,6 +67,7 @@ __export(index_exports, {
|
|
|
65
67
|
useGlitchgrab: () => useGlitchgrab,
|
|
66
68
|
useGlitchgrabActions: () => useGlitchgrabActions,
|
|
67
69
|
useGlitchgrabFeedback: () => useGlitchgrabFeedback,
|
|
70
|
+
useGlitchgrabReportThread: () => useGlitchgrabReportThread,
|
|
68
71
|
useGlitchgrabReports: () => useGlitchgrabReports
|
|
69
72
|
});
|
|
70
73
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -772,12 +775,21 @@ function signedFields(identity) {
|
|
|
772
775
|
return { userId: identity.userId, signature: identity.signature };
|
|
773
776
|
}
|
|
774
777
|
async function enhanceText(text, token, baseUrl, screenshot, context, identity) {
|
|
778
|
+
try {
|
|
779
|
+
return await enhanceTextOrThrow(text, token, baseUrl, screenshot, context, identity);
|
|
780
|
+
} catch (e) {
|
|
781
|
+
return text;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
async function enhanceTextOrThrow(text, token, baseUrl, screenshot, context, identity) {
|
|
775
785
|
var _a;
|
|
786
|
+
const trimmed = text.trim();
|
|
787
|
+
if (!trimmed) return text;
|
|
788
|
+
const unavailable = "AI enhance isn't available right now \u2014 send your report as written.";
|
|
789
|
+
let response;
|
|
776
790
|
try {
|
|
777
|
-
const trimmed = text.trim();
|
|
778
|
-
if (!trimmed) return text;
|
|
779
791
|
const url = `${baseUrl != null ? baseUrl : DEFAULT_BASE_URL}/api/v1/ai/enhance-text`;
|
|
780
|
-
|
|
792
|
+
response = await fetch(url, {
|
|
781
793
|
method: "POST",
|
|
782
794
|
headers: {
|
|
783
795
|
"Content-Type": "application/json",
|
|
@@ -790,15 +802,20 @@ async function enhanceText(text, token, baseUrl, screenshot, context, identity)
|
|
|
790
802
|
...signedFields(identity)
|
|
791
803
|
})
|
|
792
804
|
});
|
|
793
|
-
if (!response.ok) return text;
|
|
794
|
-
const envelope = await response.json();
|
|
795
|
-
if ((envelope == null ? void 0 : envelope.success) && typeof ((_a = envelope.data) == null ? void 0 : _a.text) === "string") {
|
|
796
|
-
return envelope.data.text;
|
|
797
|
-
}
|
|
798
|
-
return text;
|
|
799
805
|
} catch (e) {
|
|
800
|
-
|
|
806
|
+
throw new Error(unavailable);
|
|
807
|
+
}
|
|
808
|
+
if (response.status === 429) {
|
|
809
|
+
throw new Error("Too many AI enhance tries \u2014 wait a while, or send your report as written.");
|
|
810
|
+
}
|
|
811
|
+
const envelope = await response.json().catch(() => null);
|
|
812
|
+
if (response.ok && (envelope == null ? void 0 : envelope.success) && typeof ((_a = envelope.data) == null ? void 0 : _a.text) === "string") {
|
|
813
|
+
return envelope.data.text;
|
|
801
814
|
}
|
|
815
|
+
if (response.status === 400 && typeof (envelope == null ? void 0 : envelope.error) === "string") {
|
|
816
|
+
throw new Error(envelope.error);
|
|
817
|
+
}
|
|
818
|
+
throw new Error(unavailable);
|
|
802
819
|
}
|
|
803
820
|
async function findSimilarIssues(description, token, baseUrl, identity, files) {
|
|
804
821
|
var _a;
|
|
@@ -5550,6 +5567,7 @@ function ReportDialog({
|
|
|
5550
5567
|
const [aiConversationId, setAiConversationId] = (0, import_react.useState)(null);
|
|
5551
5568
|
const [issueTitle, setIssueTitle] = (0, import_react.useState)("");
|
|
5552
5569
|
const [isEnhanced, setIsEnhanced] = (0, import_react.useState)(false);
|
|
5570
|
+
const [enhanceError, setEnhanceError] = (0, import_react.useState)(null);
|
|
5553
5571
|
const [originalDescription, setOriginalDescription] = (0, import_react.useState)(
|
|
5554
5572
|
null
|
|
5555
5573
|
);
|
|
@@ -6004,6 +6022,7 @@ function ReportDialog({
|
|
|
6004
6022
|
setSelfReportFrom(null);
|
|
6005
6023
|
setVoiceError(null);
|
|
6006
6024
|
setIsEnhanced(false);
|
|
6025
|
+
setEnhanceError(null);
|
|
6007
6026
|
setOriginalDescription(null);
|
|
6008
6027
|
setAssistOpen(false);
|
|
6009
6028
|
setAssistUsed(false);
|
|
@@ -6069,6 +6088,7 @@ function ReportDialog({
|
|
|
6069
6088
|
const sep = base.trim() ? " " : "";
|
|
6070
6089
|
setDescriptionFromVoice(base + sep + text.trim());
|
|
6071
6090
|
setValidationError(null);
|
|
6091
|
+
setEnhanceError(null);
|
|
6072
6092
|
setIsEnhanced(false);
|
|
6073
6093
|
setOriginalDescription(null);
|
|
6074
6094
|
}
|
|
@@ -7164,6 +7184,7 @@ function ReportDialog({
|
|
|
7164
7184
|
notePushToTalkEdit();
|
|
7165
7185
|
setDescription(e.target.value);
|
|
7166
7186
|
if (validationError) setValidationError(null);
|
|
7187
|
+
if (enhanceError) setEnhanceError(null);
|
|
7167
7188
|
if (isEnhanced) {
|
|
7168
7189
|
setIsEnhanced(false);
|
|
7169
7190
|
setOriginalDescription(null);
|
|
@@ -7285,6 +7306,7 @@ function ReportDialog({
|
|
|
7285
7306
|
var _a2;
|
|
7286
7307
|
if (!description.trim() || isEnhancing) return;
|
|
7287
7308
|
setIsEnhancing(true);
|
|
7309
|
+
setEnhanceError(null);
|
|
7288
7310
|
try {
|
|
7289
7311
|
const polished = await enhanceText2(
|
|
7290
7312
|
description,
|
|
@@ -7297,6 +7319,10 @@ function ReportDialog({
|
|
|
7297
7319
|
if (validationError)
|
|
7298
7320
|
setValidationError(null);
|
|
7299
7321
|
}
|
|
7322
|
+
} catch (err) {
|
|
7323
|
+
setEnhanceError(
|
|
7324
|
+
err instanceof Error && err.message ? err.message : "AI enhance isn't available right now \u2014 send your report as written."
|
|
7325
|
+
);
|
|
7300
7326
|
} finally {
|
|
7301
7327
|
setIsEnhancing(false);
|
|
7302
7328
|
}
|
|
@@ -7555,6 +7581,20 @@ function ReportDialog({
|
|
|
7555
7581
|
children: voiceError
|
|
7556
7582
|
}
|
|
7557
7583
|
),
|
|
7584
|
+
enhanceError && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
7585
|
+
"p",
|
|
7586
|
+
{
|
|
7587
|
+
role: "alert",
|
|
7588
|
+
style: {
|
|
7589
|
+
color: "#ef4444",
|
|
7590
|
+
fontSize: "11px",
|
|
7591
|
+
lineHeight: 1.5,
|
|
7592
|
+
marginTop: "4px",
|
|
7593
|
+
marginBottom: 0
|
|
7594
|
+
},
|
|
7595
|
+
children: enhanceError
|
|
7596
|
+
}
|
|
7597
|
+
),
|
|
7558
7598
|
assistNotice && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
7559
7599
|
"p",
|
|
7560
7600
|
{
|
|
@@ -10308,21 +10348,27 @@ function GlitchgrabProviderInner({
|
|
|
10308
10348
|
() => ({ userId: signedUserId != null ? signedUserId : null, signature }),
|
|
10309
10349
|
[signedUserId, signature]
|
|
10310
10350
|
);
|
|
10351
|
+
const enhanceForDialog = (0, import_react6.useCallback)(
|
|
10352
|
+
async (text, screenshot) => {
|
|
10353
|
+
const ctx = captureContext(visitedPagesRef.current);
|
|
10354
|
+
const context = {
|
|
10355
|
+
url: ctx.url,
|
|
10356
|
+
visitedPages: ctx.visitedPages.slice(-5),
|
|
10357
|
+
breadcrumbs: ctx.breadcrumbs.slice(-10).map((b) => ({ type: b.type, message: b.message }))
|
|
10358
|
+
};
|
|
10359
|
+
return await enhanceTextOrThrow(text, token, baseUrl, screenshot, context, identity);
|
|
10360
|
+
},
|
|
10361
|
+
[token, baseUrl, identity]
|
|
10362
|
+
);
|
|
10311
10363
|
const enhance = (0, import_react6.useCallback)(
|
|
10312
10364
|
async (text, screenshot) => {
|
|
10313
10365
|
try {
|
|
10314
|
-
|
|
10315
|
-
const context = {
|
|
10316
|
-
url: ctx.url,
|
|
10317
|
-
visitedPages: ctx.visitedPages.slice(-5),
|
|
10318
|
-
breadcrumbs: ctx.breadcrumbs.slice(-10).map((b) => ({ type: b.type, message: b.message }))
|
|
10319
|
-
};
|
|
10320
|
-
return await enhanceText(text, token, baseUrl, screenshot, context, identity);
|
|
10366
|
+
return await enhanceForDialog(text, screenshot);
|
|
10321
10367
|
} catch (e) {
|
|
10322
10368
|
return text;
|
|
10323
10369
|
}
|
|
10324
10370
|
},
|
|
10325
|
-
[
|
|
10371
|
+
[enhanceForDialog]
|
|
10326
10372
|
);
|
|
10327
10373
|
const assist = (0, import_react6.useCallback)(
|
|
10328
10374
|
async (params) => {
|
|
@@ -10496,7 +10542,7 @@ function GlitchgrabProviderInner({
|
|
|
10496
10542
|
{
|
|
10497
10543
|
report,
|
|
10498
10544
|
sendFeedback: feedback,
|
|
10499
|
-
enhanceText: aiAssist && !aiBlockedUnsigned ?
|
|
10545
|
+
enhanceText: aiAssist && !aiBlockedUnsigned ? enhanceForDialog : void 0,
|
|
10500
10546
|
assist: aiAssist && !aiBlockedUnsigned ? assist : void 0,
|
|
10501
10547
|
findSimilarIssues: aiAssist && !aiBlockedUnsigned ? findSimilar : void 0,
|
|
10502
10548
|
readFile: aiAssist && !aiBlockedUnsigned ? readFile : void 0,
|
|
@@ -10841,6 +10887,87 @@ function useGlitchgrabActions({
|
|
|
10841
10887
|
error
|
|
10842
10888
|
};
|
|
10843
10889
|
}
|
|
10890
|
+
async function fetchGlitchgrabReportThread({
|
|
10891
|
+
token,
|
|
10892
|
+
reportId
|
|
10893
|
+
}) {
|
|
10894
|
+
var _a, _b, _c;
|
|
10895
|
+
const res = await fetch(`${BASE_URL}/api/v1/sdk/reports/${encodeURIComponent(reportId)}`, {
|
|
10896
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
10897
|
+
});
|
|
10898
|
+
const data = await res.json().catch(() => ({}));
|
|
10899
|
+
if (!res.ok || !data.success) throw new Error((_a = data.error) != null ? _a : "Failed to fetch report");
|
|
10900
|
+
return { ...data.data, comments: (_c = (_b = data.data) == null ? void 0 : _b.comments) != null ? _c : [] };
|
|
10901
|
+
}
|
|
10902
|
+
async function postGlitchgrabReportComment({
|
|
10903
|
+
token,
|
|
10904
|
+
reportId,
|
|
10905
|
+
message,
|
|
10906
|
+
reporterName,
|
|
10907
|
+
reporterEmail
|
|
10908
|
+
}) {
|
|
10909
|
+
var _a;
|
|
10910
|
+
const res = await fetch(`${BASE_URL}/api/v1/sdk/reports/${encodeURIComponent(reportId)}/comments`, {
|
|
10911
|
+
method: "POST",
|
|
10912
|
+
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
|
|
10913
|
+
body: JSON.stringify({ message, reporterName, reporterEmail })
|
|
10914
|
+
});
|
|
10915
|
+
const data = await res.json().catch(() => ({}));
|
|
10916
|
+
if (!res.ok || !data.success) throw new Error((_a = data.error) != null ? _a : "Failed to post comment");
|
|
10917
|
+
return data.data;
|
|
10918
|
+
}
|
|
10919
|
+
function useGlitchgrabReportThread({
|
|
10920
|
+
token,
|
|
10921
|
+
reportId,
|
|
10922
|
+
reporterName,
|
|
10923
|
+
reporterEmail
|
|
10924
|
+
}) {
|
|
10925
|
+
var _a;
|
|
10926
|
+
const [report, setReport] = (0, import_react8.useState)(null);
|
|
10927
|
+
const [isLoading, setIsLoading] = (0, import_react8.useState)(!!reportId);
|
|
10928
|
+
const [isFetching, setIsFetching] = (0, import_react8.useState)(false);
|
|
10929
|
+
const [isPosting, setIsPosting] = (0, import_react8.useState)(false);
|
|
10930
|
+
const [error, setError] = (0, import_react8.useState)(null);
|
|
10931
|
+
const refetch = (0, import_react8.useCallback)(async () => {
|
|
10932
|
+
if (!token || !reportId) {
|
|
10933
|
+
setReport(null);
|
|
10934
|
+
setIsLoading(false);
|
|
10935
|
+
return;
|
|
10936
|
+
}
|
|
10937
|
+
setIsFetching(true);
|
|
10938
|
+
setError(null);
|
|
10939
|
+
try {
|
|
10940
|
+
setReport(await fetchGlitchgrabReportThread({ token, reportId }));
|
|
10941
|
+
} catch (e) {
|
|
10942
|
+
setError(e instanceof Error ? e.message : "Network error");
|
|
10943
|
+
} finally {
|
|
10944
|
+
setIsLoading(false);
|
|
10945
|
+
setIsFetching(false);
|
|
10946
|
+
}
|
|
10947
|
+
}, [token, reportId]);
|
|
10948
|
+
(0, import_react8.useEffect)(() => {
|
|
10949
|
+
refetch();
|
|
10950
|
+
}, [refetch]);
|
|
10951
|
+
const addComment = (0, import_react8.useCallback)(
|
|
10952
|
+
async (message) => {
|
|
10953
|
+
if (!token || !reportId || !message.trim()) return false;
|
|
10954
|
+
setIsPosting(true);
|
|
10955
|
+
setError(null);
|
|
10956
|
+
try {
|
|
10957
|
+
await postGlitchgrabReportComment({ token, reportId, message: message.trim(), reporterName, reporterEmail });
|
|
10958
|
+
await refetch();
|
|
10959
|
+
return true;
|
|
10960
|
+
} catch (e) {
|
|
10961
|
+
setError(e instanceof Error ? e.message : "Failed to post comment");
|
|
10962
|
+
return false;
|
|
10963
|
+
} finally {
|
|
10964
|
+
setIsPosting(false);
|
|
10965
|
+
}
|
|
10966
|
+
},
|
|
10967
|
+
[token, reportId, reporterName, reporterEmail, refetch]
|
|
10968
|
+
);
|
|
10969
|
+
return { report, comments: (_a = report == null ? void 0 : report.comments) != null ? _a : [], isLoading, isFetching, isPosting, error, refetch, addComment };
|
|
10970
|
+
}
|
|
10844
10971
|
|
|
10845
10972
|
// src/use-feedback.ts
|
|
10846
10973
|
var import_react9 = require("react");
|
|
@@ -10922,12 +11049,14 @@ function useGlitchgrabFeedback(query) {
|
|
|
10922
11049
|
computeSignature,
|
|
10923
11050
|
enhanceText,
|
|
10924
11051
|
fetchGlitchgrabFeedback,
|
|
11052
|
+
fetchGlitchgrabReportThread,
|
|
10925
11053
|
fetchGlitchgrabReports,
|
|
10926
11054
|
getAppContext,
|
|
10927
11055
|
getBreadcrumbs,
|
|
10928
11056
|
getShortcutLabel,
|
|
10929
11057
|
initBreadcrumbs,
|
|
10930
11058
|
matchesShortcut,
|
|
11059
|
+
postGlitchgrabReportComment,
|
|
10931
11060
|
sanitizeUrl,
|
|
10932
11061
|
sendFeedback,
|
|
10933
11062
|
sendLead,
|
|
@@ -10938,6 +11067,7 @@ function useGlitchgrabFeedback(query) {
|
|
|
10938
11067
|
useGlitchgrab,
|
|
10939
11068
|
useGlitchgrabActions,
|
|
10940
11069
|
useGlitchgrabFeedback,
|
|
11070
|
+
useGlitchgrabReportThread,
|
|
10941
11071
|
useGlitchgrabReports
|
|
10942
11072
|
});
|
|
10943
11073
|
//# sourceMappingURL=index.js.map
|