glitchgrab 1.58.3 → 1.59.1

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 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
@@ -1001,6 +1037,25 @@ interface CallsOptions {
1001
1037
  }
1002
1038
  ```
1003
1039
 
1040
+ ## How do I do something once a visitor books a demo?
1041
+
1042
+ Open the dialog yourself and pass `onBooked`. `intro` puts one line of your own
1043
+ above the dialog's title, so the visitor knows why you are asking.
1044
+
1045
+ ```tsx
1046
+ const { openBookingDialog } = useGlitchgrab();
1047
+
1048
+ openBookingDialog({
1049
+ intro: "Book a short call — the live demo opens the moment you're booked.",
1050
+ onBooked: ({ bookingId }) => {
1051
+ // Runs once, after the phone code when one is asked. The details come from
1052
+ // the browser: look `bookingId` up with listBookings() on your server
1053
+ // before you trust it.
1054
+ startDemo(bookingId);
1055
+ },
1056
+ });
1057
+ ```
1058
+
1004
1059
  ## How do I change demo booking settings from my admin panel?
1005
1060
 
1006
1061
  The same server key reads and writes the project's demo booking settings —
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { f as GlitchgrabProviderProps, U as UseGlitchgrabReturn, R as ReportButtonProps, F as FeedbackButtonProps, g as GlitchgrabSession, C as CaptureErrorOptions, e as GlitchgrabFeedback, a as BreadcrumbType, B as Breadcrumb, b as CapturedContext, D as DeviceInfo, c as FeedbackPayload, d as FeedbackResult, L as LeadInput, h as LeadResult, i as ReportPayload, j as ReportResult } from './types-BpTLWJ1y.mjs';
3
- export { G as GlitchgrabConfig, k as ReportSeverity, l as ReportType, m as RuntimeInfo } from './types-BpTLWJ1y.mjs';
2
+ import { h as GlitchgrabProviderProps, U as UseGlitchgrabReturn, R as ReportButtonProps, B as BookedDemo, F as FeedbackButtonProps, i as GlitchgrabSession, C as CaptureErrorOptions, g as GlitchgrabFeedback, c as BreadcrumbType, b as Breadcrumb, d as CapturedContext, D as DeviceInfo, e as FeedbackPayload, f as FeedbackResult, L as LeadInput, j as LeadResult, k as ReportPayload, l as ReportResult } from './types-BlMF6wzX.mjs';
3
+ export { a as BookingDialogOptions, G as GlitchgrabConfig, m as ReportSeverity, n as ReportType, o as RuntimeInfo } from './types-BlMF6wzX.mjs';
4
4
  import * as React from 'react';
5
5
  import { ReactNode } from 'react';
6
6
 
@@ -81,7 +81,7 @@ declare function BookDemoButton({ label, className, children, }: {
81
81
  }) => ReactNode;
82
82
  }): react_jsx_runtime.JSX.Element;
83
83
 
84
- declare function BookingDialog({ token, baseUrl, open, onClose, preview, availabilityUrl, }: {
84
+ declare function BookingDialog({ token, baseUrl, open, onClose, preview, availabilityUrl, intro, onBooked, }: {
85
85
  token: string;
86
86
  baseUrl: string;
87
87
  open: boolean;
@@ -97,6 +97,10 @@ declare function BookingDialog({ token, baseUrl, open, onClose, preview, availab
97
97
  * holds no `gg_` token for the project. Same response shape.
98
98
  */
99
99
  availabilityUrl?: string;
100
+ /** The host's one line above the title — see `BookingDialogOptions.intro`. */
101
+ intro?: string;
102
+ /** Fired once when a booking is confirmed — see `BookingDialogOptions.onBooked`. */
103
+ onBooked?: (booking: BookedDemo) => void;
100
104
  }): react_jsx_runtime.JSX.Element | null;
101
105
 
102
106
  /**
@@ -280,6 +284,82 @@ declare function useGlitchgrabActions({ token, onSuccess, onError, }: {
280
284
  isPending: boolean;
281
285
  error: string | null;
282
286
  };
287
+ interface GlitchgrabComment {
288
+ /** GitHub login. Replies from your users post as the Glitchgrab app, with their name in the body. */
289
+ author: string;
290
+ body: string;
291
+ createdAt: string;
292
+ }
293
+ interface GlitchgrabReportThread {
294
+ id: string;
295
+ status: string;
296
+ rawInput: string | null;
297
+ createdAt: string;
298
+ issue: {
299
+ githubNumber: number;
300
+ githubUrl: string;
301
+ title: string;
302
+ body: string;
303
+ labels: string[];
304
+ severity: string | null;
305
+ /** "open" | "closed", or null when GitHub did not answer. */
306
+ githubState: string | null;
307
+ } | null;
308
+ /** Oldest first. Empty when no issue is linked yet. */
309
+ comments: GlitchgrabComment[];
310
+ }
311
+ /**
312
+ * Fetch one report with its GitHub issue and every comment on it — the team's
313
+ * replies and your user's. Throws on failure; pair it with your own data layer.
314
+ */
315
+ declare function fetchGlitchgrabReportThread({ token, reportId, }: {
316
+ token: string;
317
+ reportId: string;
318
+ }): Promise<GlitchgrabReportThread>;
319
+ /**
320
+ * Post a reply on the report's GitHub issue. It lands as the Glitchgrab app
321
+ * with "Commented by: <name>" underneath, so the team knows who said it.
322
+ * Throws on failure.
323
+ */
324
+ declare function postGlitchgrabReportComment({ token, reportId, message, reporterName, reporterEmail, }: {
325
+ token: string;
326
+ reportId: string;
327
+ message: string;
328
+ /** Defaults to the name the report was filed under. */
329
+ reporterName?: string;
330
+ reporterEmail?: string;
331
+ }): Promise<GlitchgrabComment>;
332
+ /**
333
+ * The conversation on one report: where it stands, what the team said, and a
334
+ * way for your user to reply — without a GitHub account.
335
+ *
336
+ * ```tsx
337
+ * const { report, comments, addComment, isPosting } = useGlitchgrabReportThread({
338
+ * token: process.env.NEXT_PUBLIC_GLITCHGRAB_TOKEN!,
339
+ * reportId,
340
+ * reporterName: session.user.name,
341
+ * });
342
+ * ```
343
+ *
344
+ * Never throws. `addComment` resolves `true` once the reply is on the issue
345
+ * (and the thread has reloaded), `false` with `error` set otherwise.
346
+ */
347
+ declare function useGlitchgrabReportThread({ token, reportId, reporterName, reporterEmail, }: {
348
+ token: string;
349
+ /** `reportId` from `useGlitchgrabReports` or the report submit result. Null waits. */
350
+ reportId: string | null;
351
+ reporterName?: string;
352
+ reporterEmail?: string;
353
+ }): {
354
+ report: GlitchgrabReportThread | null;
355
+ comments: GlitchgrabComment[];
356
+ isLoading: boolean;
357
+ isFetching: boolean;
358
+ isPosting: boolean;
359
+ error: string | null;
360
+ refetch: () => Promise<void>;
361
+ addComment: (message: string) => Promise<boolean>;
362
+ };
283
363
 
284
364
  interface FeedbackQuery {
285
365
  token: string;
@@ -422,4 +502,4 @@ declare function computeSignature(params: {
422
502
  declare function shouldSkipDuplicate(signature: string, windowMs?: number, now?: number): boolean;
423
503
  declare function clearDedupCache(): void;
424
504
 
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 };
505
+ export { BookDemoButton, BookedDemo, 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
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { f as GlitchgrabProviderProps, U as UseGlitchgrabReturn, R as ReportButtonProps, F as FeedbackButtonProps, g as GlitchgrabSession, C as CaptureErrorOptions, e as GlitchgrabFeedback, a as BreadcrumbType, B as Breadcrumb, b as CapturedContext, D as DeviceInfo, c as FeedbackPayload, d as FeedbackResult, L as LeadInput, h as LeadResult, i as ReportPayload, j as ReportResult } from './types-BpTLWJ1y.js';
3
- export { G as GlitchgrabConfig, k as ReportSeverity, l as ReportType, m as RuntimeInfo } from './types-BpTLWJ1y.js';
2
+ import { h as GlitchgrabProviderProps, U as UseGlitchgrabReturn, R as ReportButtonProps, B as BookedDemo, F as FeedbackButtonProps, i as GlitchgrabSession, C as CaptureErrorOptions, g as GlitchgrabFeedback, c as BreadcrumbType, b as Breadcrumb, d as CapturedContext, D as DeviceInfo, e as FeedbackPayload, f as FeedbackResult, L as LeadInput, j as LeadResult, k as ReportPayload, l as ReportResult } from './types-BlMF6wzX.js';
3
+ export { a as BookingDialogOptions, G as GlitchgrabConfig, m as ReportSeverity, n as ReportType, o as RuntimeInfo } from './types-BlMF6wzX.js';
4
4
  import * as React from 'react';
5
5
  import { ReactNode } from 'react';
6
6
 
@@ -81,7 +81,7 @@ declare function BookDemoButton({ label, className, children, }: {
81
81
  }) => ReactNode;
82
82
  }): react_jsx_runtime.JSX.Element;
83
83
 
84
- declare function BookingDialog({ token, baseUrl, open, onClose, preview, availabilityUrl, }: {
84
+ declare function BookingDialog({ token, baseUrl, open, onClose, preview, availabilityUrl, intro, onBooked, }: {
85
85
  token: string;
86
86
  baseUrl: string;
87
87
  open: boolean;
@@ -97,6 +97,10 @@ declare function BookingDialog({ token, baseUrl, open, onClose, preview, availab
97
97
  * holds no `gg_` token for the project. Same response shape.
98
98
  */
99
99
  availabilityUrl?: string;
100
+ /** The host's one line above the title — see `BookingDialogOptions.intro`. */
101
+ intro?: string;
102
+ /** Fired once when a booking is confirmed — see `BookingDialogOptions.onBooked`. */
103
+ onBooked?: (booking: BookedDemo) => void;
100
104
  }): react_jsx_runtime.JSX.Element | null;
101
105
 
102
106
  /**
@@ -280,6 +284,82 @@ declare function useGlitchgrabActions({ token, onSuccess, onError, }: {
280
284
  isPending: boolean;
281
285
  error: string | null;
282
286
  };
287
+ interface GlitchgrabComment {
288
+ /** GitHub login. Replies from your users post as the Glitchgrab app, with their name in the body. */
289
+ author: string;
290
+ body: string;
291
+ createdAt: string;
292
+ }
293
+ interface GlitchgrabReportThread {
294
+ id: string;
295
+ status: string;
296
+ rawInput: string | null;
297
+ createdAt: string;
298
+ issue: {
299
+ githubNumber: number;
300
+ githubUrl: string;
301
+ title: string;
302
+ body: string;
303
+ labels: string[];
304
+ severity: string | null;
305
+ /** "open" | "closed", or null when GitHub did not answer. */
306
+ githubState: string | null;
307
+ } | null;
308
+ /** Oldest first. Empty when no issue is linked yet. */
309
+ comments: GlitchgrabComment[];
310
+ }
311
+ /**
312
+ * Fetch one report with its GitHub issue and every comment on it — the team's
313
+ * replies and your user's. Throws on failure; pair it with your own data layer.
314
+ */
315
+ declare function fetchGlitchgrabReportThread({ token, reportId, }: {
316
+ token: string;
317
+ reportId: string;
318
+ }): Promise<GlitchgrabReportThread>;
319
+ /**
320
+ * Post a reply on the report's GitHub issue. It lands as the Glitchgrab app
321
+ * with "Commented by: <name>" underneath, so the team knows who said it.
322
+ * Throws on failure.
323
+ */
324
+ declare function postGlitchgrabReportComment({ token, reportId, message, reporterName, reporterEmail, }: {
325
+ token: string;
326
+ reportId: string;
327
+ message: string;
328
+ /** Defaults to the name the report was filed under. */
329
+ reporterName?: string;
330
+ reporterEmail?: string;
331
+ }): Promise<GlitchgrabComment>;
332
+ /**
333
+ * The conversation on one report: where it stands, what the team said, and a
334
+ * way for your user to reply — without a GitHub account.
335
+ *
336
+ * ```tsx
337
+ * const { report, comments, addComment, isPosting } = useGlitchgrabReportThread({
338
+ * token: process.env.NEXT_PUBLIC_GLITCHGRAB_TOKEN!,
339
+ * reportId,
340
+ * reporterName: session.user.name,
341
+ * });
342
+ * ```
343
+ *
344
+ * Never throws. `addComment` resolves `true` once the reply is on the issue
345
+ * (and the thread has reloaded), `false` with `error` set otherwise.
346
+ */
347
+ declare function useGlitchgrabReportThread({ token, reportId, reporterName, reporterEmail, }: {
348
+ token: string;
349
+ /** `reportId` from `useGlitchgrabReports` or the report submit result. Null waits. */
350
+ reportId: string | null;
351
+ reporterName?: string;
352
+ reporterEmail?: string;
353
+ }): {
354
+ report: GlitchgrabReportThread | null;
355
+ comments: GlitchgrabComment[];
356
+ isLoading: boolean;
357
+ isFetching: boolean;
358
+ isPosting: boolean;
359
+ error: string | null;
360
+ refetch: () => Promise<void>;
361
+ addComment: (message: string) => Promise<boolean>;
362
+ };
283
363
 
284
364
  interface FeedbackQuery {
285
365
  token: string;
@@ -422,4 +502,4 @@ declare function computeSignature(params: {
422
502
  declare function shouldSkipDuplicate(signature: string, windowMs?: number, now?: number): boolean;
423
503
  declare function clearDedupCache(): void;
424
504
 
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 };
505
+ export { BookDemoButton, BookedDemo, 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 };