@mushi-mushi/core 1.5.0 → 1.7.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/CONTRIBUTING.md +0 -11
- package/dist/index.cjs +12 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +131 -68
- package/dist/index.d.ts +131 -68
- package/dist/index.js +12 -1
- package/dist/index.js.map +1 -1
- package/package.json +14 -14
package/dist/index.d.cts
CHANGED
|
@@ -19,43 +19,12 @@ interface MushiConfig {
|
|
|
19
19
|
integrations?: MushiIntegrationsConfig;
|
|
20
20
|
offline?: MushiOfflineConfig;
|
|
21
21
|
rewards?: MushiRewardsConfig;
|
|
22
|
-
/**
|
|
23
|
-
* Sentry-spec-1.0 hook fired AFTER preFilter / on-device classifier /
|
|
24
|
-
* rate-limit gates pass and BEFORE the report is sent or queued.
|
|
25
|
-
* Return:
|
|
26
|
-
* - the report (possibly modified) → submit as-is
|
|
27
|
-
* - a Promise<MushiReport> → await, then submit
|
|
28
|
-
* - `null` → drop the report silently (no `report:sent`/`:failed` event)
|
|
29
|
-
*
|
|
30
|
-
* Use this for app-level redaction of sensitive metadata, hard-coded
|
|
31
|
-
* tag overrides, or last-mile category routing. Errors thrown inside
|
|
32
|
-
* the hook are caught and logged; the report still ships unchanged so
|
|
33
|
-
* a buggy hook never silently swallows feedback.
|
|
34
|
-
*
|
|
35
|
-
* Mirrors Sentry's [SDK feedback spec §4](https://develop.sentry.dev/sdk/telemetry/feedbacks/)
|
|
36
|
-
* `beforeSendFeedback` callback.
|
|
37
|
-
*/
|
|
38
|
-
beforeSendFeedback?: (report: MushiReport) => MushiReport | Promise<MushiReport | null> | null;
|
|
39
|
-
/**
|
|
40
|
-
* Sentry-spec-1.0 callback fired exactly once on `init()` after the
|
|
41
|
-
* SDK detects that the previous browser session ended in a crash
|
|
42
|
-
* (uncaught exception, unhandled rejection, or hard navigate during
|
|
43
|
-
* unfinished submit). Use it to surface a "Tell us what went wrong?"
|
|
44
|
-
* prompt to the user — the SDK does NOT auto-open the widget so the
|
|
45
|
-
* host app can decide on copy and timing.
|
|
46
|
-
*
|
|
47
|
-
* The promise resolves with `true` when a crash was detected, `false`
|
|
48
|
-
* when the previous run ended cleanly, and `null` when the SDK can't
|
|
49
|
-
* tell (typically: localStorage unavailable, or first-ever load).
|
|
50
|
-
*
|
|
51
|
-
* Mirrors Sentry's [SDK feedback spec §6](https://develop.sentry.dev/sdk/telemetry/feedbacks/)
|
|
52
|
-
* `onCrashedLastRun` hook.
|
|
53
|
-
*/
|
|
54
|
-
onCrashedLastRun?: (info: {
|
|
55
|
-
crashed: boolean | null;
|
|
56
|
-
}) => void;
|
|
57
22
|
debug?: boolean;
|
|
58
23
|
enabled?: boolean;
|
|
24
|
+
/** Hook called before a report is sent. Return null to cancel, or return the (possibly modified) report. */
|
|
25
|
+
beforeSendFeedback?: (report: MushiReport) => MushiReport | null | Promise<MushiReport | null>;
|
|
26
|
+
/** Called once if the app crashed during the previous session. */
|
|
27
|
+
onCrashedLastRun?: (crashed: boolean) => void;
|
|
59
28
|
}
|
|
60
29
|
interface MushiSentryConfig {
|
|
61
30
|
dsn?: string;
|
|
@@ -78,9 +47,17 @@ interface MushiWidgetConfig {
|
|
|
78
47
|
zIndex?: number;
|
|
79
48
|
/**
|
|
80
49
|
* Controls how, or whether, the default trigger is injected.
|
|
81
|
-
* `auto`
|
|
50
|
+
* `auto` — historical floating stamp FAB.
|
|
51
|
+
* `banner` — slim full-width header strip (recommended default; less obtrusive
|
|
52
|
+
* than a FAB and visible even when the SDK launcher is `hide()`'d).
|
|
53
|
+
* Pair with `bannerConfig` to customise appearance.
|
|
54
|
+
*/
|
|
55
|
+
trigger?: 'auto' | 'banner' | 'edge-tab' | 'attach' | 'manual' | 'hidden';
|
|
56
|
+
/**
|
|
57
|
+
* Configuration for the header-banner launcher mode.
|
|
58
|
+
* Only applies when `trigger === 'banner'`.
|
|
82
59
|
*/
|
|
83
|
-
|
|
60
|
+
bannerConfig?: MushiBannerConfig;
|
|
84
61
|
/** CSS selector used when `trigger` is `attach`. */
|
|
85
62
|
attachToSelector?: string;
|
|
86
63
|
/**
|
|
@@ -109,13 +86,65 @@ interface MushiWidgetConfig {
|
|
|
109
86
|
*/
|
|
110
87
|
betaMode?: MushiBetaModeConfig;
|
|
111
88
|
/**
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
89
|
+
* Absolute base URL of the Mushi admin console (e.g. `https://mushi.example.com`).
|
|
90
|
+
* When set, the success step surfaces a one-tap link to the user's own report
|
|
91
|
+
* on the console so they can watch the status change in real time. Without
|
|
92
|
+
* this the success step still confirms submission but cannot deep-link.
|
|
93
|
+
*
|
|
94
|
+
* This is intentionally separate from the API endpoint — production apps
|
|
95
|
+
* usually have the API on `api.mushi.example.com` and the console on
|
|
96
|
+
* `app.mushi.example.com`.
|
|
97
|
+
*/
|
|
98
|
+
dashboardUrl?: string;
|
|
99
|
+
/**
|
|
100
|
+
* Override the SLA copy shown in the success step's "what happens next"
|
|
101
|
+
* line. Defaults to "We aim to review within 48h". Set to an empty string
|
|
102
|
+
* to hide the line entirely (e.g. internal-only deployments where SLA
|
|
103
|
+
* messaging would be over-promising).
|
|
104
|
+
*/
|
|
105
|
+
responseSlaLabel?: string;
|
|
106
|
+
/**
|
|
107
|
+
* Show a first-class "Feature request" card at the top of the category
|
|
108
|
+
* step. Defaults to true. Set to false for production-only deployments
|
|
109
|
+
* where you don't want to invite feature ideas through the widget.
|
|
110
|
+
* Internally this maps to `category='other'` with
|
|
111
|
+
* `user_category='Feature request'` so no DB migration is needed.
|
|
116
112
|
*/
|
|
113
|
+
featureRequestCard?: boolean;
|
|
114
|
+
/** Override the localised label for the feature-request card. */
|
|
115
|
+
featureRequestLabel?: string;
|
|
116
|
+
/** Override the helper text shown under the feature-request card. */
|
|
117
|
+
featureRequestDescription?: string;
|
|
118
|
+
/** Minimum description character count before the submit button enables. */
|
|
117
119
|
minDescriptionLength?: number;
|
|
118
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Configuration for the `trigger: 'banner'` header-strip launcher.
|
|
123
|
+
*
|
|
124
|
+
* The banner renders as a slim, full-width strip pinned to the top of the
|
|
125
|
+
* viewport (or bottom if `position === 'bottom'`). It is styled to match the
|
|
126
|
+
* app's brand accent and dismissed per-session via a ✕ button.
|
|
127
|
+
*
|
|
128
|
+
* Variants
|
|
129
|
+
* --------
|
|
130
|
+
* `neon` — lime / electric-green strip (high contrast, dev / beta tool feel).
|
|
131
|
+
* `brand` — uses the Mushi vermillion accent (editorial, app-quality feel).
|
|
132
|
+
* `subtle` — near-invisible hairline with muted text (least disruptive).
|
|
133
|
+
*/
|
|
134
|
+
interface MushiBannerConfig {
|
|
135
|
+
/** Visual style of the banner strip. Defaults to `'brand'`. */
|
|
136
|
+
variant?: 'neon' | 'brand' | 'subtle';
|
|
137
|
+
/** 'top' pins the banner below any existing sticky headers; 'bottom' pins above bottom navs. Defaults to 'top'. */
|
|
138
|
+
position?: 'top' | 'bottom';
|
|
139
|
+
/** Override the call-to-action text in the banner. Defaults to 'Report a bug'. */
|
|
140
|
+
bugCta?: string;
|
|
141
|
+
/** Show a "✨ Request a feature" button alongside the bug button. Defaults to true. */
|
|
142
|
+
featureCta?: boolean;
|
|
143
|
+
/** Override the feature-request button label. */
|
|
144
|
+
featureCtaLabel?: string;
|
|
145
|
+
/** CSS z-index of the banner element. Defaults to the widget's configured zIndex. */
|
|
146
|
+
zIndex?: number;
|
|
147
|
+
}
|
|
119
148
|
interface MushiBetaModeConfig {
|
|
120
149
|
enabled?: boolean;
|
|
121
150
|
/** Display name of the app shown in the beta strip. Defaults to 'This app'. */
|
|
@@ -240,6 +269,17 @@ interface MushiPrivacyConfig {
|
|
|
240
269
|
maskSelectors?: string[];
|
|
241
270
|
/** DOM subtrees to remove from screenshots before upload. */
|
|
242
271
|
blockSelectors?: string[];
|
|
272
|
+
/**
|
|
273
|
+
* CSS selectors whose matching elements are blacked-out (filled with an
|
|
274
|
+
* opaque black rectangle) in screenshots before upload. Intended for
|
|
275
|
+
* sensitive fields that should never appear in any form — passwords, PII,
|
|
276
|
+
* financial data. Applied in addition to `maskSelectors`.
|
|
277
|
+
*
|
|
278
|
+
* Default: `['input[type="password"]', '[data-mushi-redact]']`
|
|
279
|
+
*
|
|
280
|
+
* To disable the default redaction, pass an empty array.
|
|
281
|
+
*/
|
|
282
|
+
redactSelectors?: string[];
|
|
243
283
|
/** Let reporters remove an attached screenshot before submitting. Defaults to true. */
|
|
244
284
|
allowUserRemoveScreenshot?: boolean;
|
|
245
285
|
}
|
|
@@ -249,6 +289,38 @@ interface MushiProactiveConfig {
|
|
|
249
289
|
longTask?: boolean;
|
|
250
290
|
apiCascade?: boolean | MushiApiCascadeConfig;
|
|
251
291
|
cooldown?: MushiCooldownConfig;
|
|
292
|
+
/**
|
|
293
|
+
* Beta-mode nudge: fire after the user has been on the same route for
|
|
294
|
+
* `thresholdMs` continuous milliseconds (default 5min). Pass `true` to
|
|
295
|
+
* accept the default threshold, or a config object to override. Use
|
|
296
|
+
* conservatively — set the per-session cap in `cooldown` to avoid
|
|
297
|
+
* nag fatigue.
|
|
298
|
+
*/
|
|
299
|
+
pageDwell?: boolean | MushiPageDwellConfig;
|
|
300
|
+
/**
|
|
301
|
+
* One-shot welcome prompt for first-time visitors. Fires `delayMs` after
|
|
302
|
+
* `Mushi.init` (default 45s) and is suppressed permanently after the
|
|
303
|
+
* first fire via localStorage. Recommended for beta deployments.
|
|
304
|
+
*/
|
|
305
|
+
firstSession?: boolean | MushiFirstSessionConfig;
|
|
306
|
+
}
|
|
307
|
+
interface MushiPageDwellConfig {
|
|
308
|
+
/** Continuous dwell time before firing. Defaults to 5 minutes. */
|
|
309
|
+
thresholdMs?: number;
|
|
310
|
+
/**
|
|
311
|
+
* Route path prefixes (or glob-style patterns with `*`) that suppress the
|
|
312
|
+
* dwell nudge. Auth routes are excluded by default so users aren't prompted
|
|
313
|
+
* during login/signup flows.
|
|
314
|
+
*
|
|
315
|
+
* Default: `['/login', '/logout', '/signup', '/sso/*', '/auth/*']`
|
|
316
|
+
*/
|
|
317
|
+
excludeRoutes?: string[];
|
|
318
|
+
}
|
|
319
|
+
interface MushiFirstSessionConfig {
|
|
320
|
+
/** Delay before firing the welcome nudge. Defaults to 45 seconds. */
|
|
321
|
+
delayMs?: number;
|
|
322
|
+
/** Override the localStorage key used to mark the user as welcomed. */
|
|
323
|
+
storageKey?: string;
|
|
252
324
|
}
|
|
253
325
|
type MushiUrlMatcher = string | RegExp;
|
|
254
326
|
interface MushiApiCascadeConfig {
|
|
@@ -704,32 +776,16 @@ interface MushiPerformanceMetrics {
|
|
|
704
776
|
lcp?: number;
|
|
705
777
|
cls?: number;
|
|
706
778
|
fid?: number;
|
|
707
|
-
/**
|
|
708
|
-
* Interaction to Next Paint — the worst-observed user interaction
|
|
709
|
-
* latency (ms) since SDK init. Replaces FID as a Core Web Vital
|
|
710
|
-
* since March 2024. Captured via `PerformanceObserver({ type: 'event',
|
|
711
|
-
* durationThreshold: 40 })` per the [web-vitals INP spec](https://web.dev/articles/inp).
|
|
712
|
-
*/
|
|
713
779
|
inp?: number;
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
* interaction. Lets the triage UI surface "the slow click was on
|
|
717
|
-
* <button.checkout>" rather than just "1200 ms INP".
|
|
718
|
-
*/
|
|
780
|
+
ttfb?: number;
|
|
781
|
+
longTasks?: number;
|
|
719
782
|
inpAttribution?: {
|
|
720
|
-
/** PerformanceEventTiming.name (`pointerdown`, `keydown`, …). */
|
|
721
783
|
eventType?: string;
|
|
722
|
-
/** Tag + id + first class of the element that triggered the slow event. */
|
|
723
784
|
targetSelector?: string;
|
|
724
|
-
/** Time between the user input and the start of event processing. */
|
|
725
785
|
inputDelay?: number;
|
|
726
|
-
/** Time spent running the event handler. */
|
|
727
786
|
processingDuration?: number;
|
|
728
|
-
/** Time between handler end and the next paint. */
|
|
729
787
|
presentationDelay?: number;
|
|
730
788
|
};
|
|
731
|
-
ttfb?: number;
|
|
732
|
-
longTasks?: number;
|
|
733
789
|
}
|
|
734
790
|
interface MushiSelectedElement {
|
|
735
791
|
tagName: string;
|
|
@@ -762,14 +818,7 @@ interface MushiTimelineEntry {
|
|
|
762
818
|
kind: MushiTimelineKind;
|
|
763
819
|
payload: Record<string, unknown>;
|
|
764
820
|
}
|
|
765
|
-
type MushiEventType = 'report:submitted' | 'report:queued' | 'report:sent' | 'report:failed'
|
|
766
|
-
/**
|
|
767
|
-
* Fired when the submitted report has been picked up by a Cursor Cloud
|
|
768
|
-
* Agent and an automated fix is in progress. `data.agentId` is the
|
|
769
|
-
* Cursor agent run ID (bc-…); `data.fixId` is the mushi fix_attempt UUID.
|
|
770
|
-
* Useful for showing a toast: "A Cursor agent is working on your report".
|
|
771
|
-
*/
|
|
772
|
-
| 'report:dispatched' | 'widget:opened' | 'widget:closed' | 'proactive:triggered' | 'proactive:dismissed';
|
|
821
|
+
type MushiEventType = 'report:submitted' | 'report:queued' | 'report:sent' | 'report:failed' | 'widget:opened' | 'widget:closed' | 'proactive:triggered' | 'proactive:dismissed' | 'report:dispatched';
|
|
773
822
|
type MushiEventHandler = (event: {
|
|
774
823
|
type: MushiEventType;
|
|
775
824
|
data?: unknown;
|
|
@@ -786,8 +835,16 @@ interface MushiDiagnosticsResult {
|
|
|
786
835
|
sdkVersion: string;
|
|
787
836
|
}
|
|
788
837
|
interface MushiSDKInstance {
|
|
838
|
+
/**
|
|
839
|
+
* Open the reporter widget. With no options, opens to the category
|
|
840
|
+
* picker so the user can choose between bug categories and the
|
|
841
|
+
* feature-request shortcut. Pass `{ category }` to deep-link into a
|
|
842
|
+
* specific bug intent, or `{ featureRequest: true }` to deep-link into
|
|
843
|
+
* the feature-request description step (skips intent picker).
|
|
844
|
+
*/
|
|
789
845
|
report(options?: {
|
|
790
846
|
category?: MushiReportCategory;
|
|
847
|
+
featureRequest?: boolean;
|
|
791
848
|
}): void;
|
|
792
849
|
on(event: MushiEventType, handler: MushiEventHandler): () => void;
|
|
793
850
|
setUser(user: {
|
|
@@ -888,6 +945,12 @@ interface MushiSDKInstance {
|
|
|
888
945
|
* No-op when rewards are disabled or the user has not opted in.
|
|
889
946
|
*/
|
|
890
947
|
recordActivity(action: string, metadata?: Record<string, unknown>): void;
|
|
948
|
+
/**
|
|
949
|
+
* Briefly animate the bug-report trigger button to draw the user's
|
|
950
|
+
* attention without opening the full widget. Ideal for subtle "feedback
|
|
951
|
+
* welcome" nudges (first-session, beta-onboarding).
|
|
952
|
+
*/
|
|
953
|
+
pulseTrigger(): void;
|
|
891
954
|
}
|
|
892
955
|
interface MushiCaptureExceptionOptions {
|
|
893
956
|
/** Override the default `'bug'` category (e.g. `'slow'` for timeouts). */
|
|
@@ -1339,4 +1402,4 @@ declare function createLogger(options: LoggerOptions): Logger;
|
|
|
1339
1402
|
*/
|
|
1340
1403
|
declare const noopLogger: Logger;
|
|
1341
1404
|
|
|
1342
|
-
export { type ApiClientOptions, type BreadcrumbBuffer, type BreadcrumbBufferOptions, DEFAULT_API_ENDPOINT, type LogEntry, type LogFormat, type LogLevel, type Logger, type LoggerOptions, MUSHI_INTERNAL_HEADER, MUSHI_INTERNAL_INIT_MARKER, type MushiActivityEvent, type MushiApiCascadeConfig, type MushiApiClient, type MushiApiResponse, type MushiBetaChangelogEntry, type MushiBetaModeConfig, type MushiBreadcrumb, type MushiCaptureConfig, type MushiCaptureEventInput, type MushiCaptureExceptionOptions, type MushiConfig, type MushiConsoleEntry, type MushiCooldownConfig, type MushiDiagnosticsResult, type MushiDiscoverInventoryConfig, type MushiDiscoveryEventPayload, type MushiEnvironment, type MushiEventHandler, type MushiEventType, type MushiIntegrationsConfig, type MushiInternalRequestKind, type MushiNetworkEntry, type MushiOfflineConfig, type MushiOnDeviceClassifier, type MushiOnDeviceClassifierInput, type MushiOnDeviceClassifierResult, type MushiPerformanceMetrics, type MushiPreFilterConfig, type MushiPreset, type MushiPrivacyConfig, type MushiProactiveConfig, type MushiRegion, type MushiReport, type MushiReportBuilder, type MushiReportCategory, type MushiReportStatus, type MushiReporterComment, type MushiReporterReport, type MushiReputationResult, type MushiRewardsConfig, type MushiRuntimeSdkConfig, type MushiSDKInstance, type MushiSdkVersionInfo, type MushiSelectedElement, type MushiSentryConfig, type MushiSentryContext, type MushiTierResult, type MushiTimelineEntry, type MushiTimelineKind, type MushiUrlMatcher, type MushiWidgetAnchor, type MushiWidgetConfig, type NormalisedException, type OfflineQueue, type PiiScrubberConfig, type PreFilterResult, REGION_ENDPOINTS, type RateLimiter, type RateLimiterConfig, captureEnvironment, createApiClient, createBreadcrumbBuffer, createLogger, createOfflineQueue, createPiiScrubber, createPreFilter, createRateLimiter, getDeviceFingerprintHash, getReporterToken, getSessionId, noopLogger, normaliseThrown, resolveRegionEndpoint, scrubPii };
|
|
1405
|
+
export { type ApiClientOptions, type BreadcrumbBuffer, type BreadcrumbBufferOptions, DEFAULT_API_ENDPOINT, type LogEntry, type LogFormat, type LogLevel, type Logger, type LoggerOptions, MUSHI_INTERNAL_HEADER, MUSHI_INTERNAL_INIT_MARKER, type MushiActivityEvent, type MushiApiCascadeConfig, type MushiApiClient, type MushiApiResponse, type MushiBannerConfig, type MushiBetaChangelogEntry, type MushiBetaModeConfig, type MushiBreadcrumb, type MushiCaptureConfig, type MushiCaptureEventInput, type MushiCaptureExceptionOptions, type MushiConfig, type MushiConsoleEntry, type MushiCooldownConfig, type MushiDiagnosticsResult, type MushiDiscoverInventoryConfig, type MushiDiscoveryEventPayload, type MushiEnvironment, type MushiEventHandler, type MushiEventType, type MushiIntegrationsConfig, type MushiInternalRequestKind, type MushiNetworkEntry, type MushiOfflineConfig, type MushiOnDeviceClassifier, type MushiOnDeviceClassifierInput, type MushiOnDeviceClassifierResult, type MushiPerformanceMetrics, type MushiPreFilterConfig, type MushiPreset, type MushiPrivacyConfig, type MushiProactiveConfig, type MushiRegion, type MushiReport, type MushiReportBuilder, type MushiReportCategory, type MushiReportStatus, type MushiReporterComment, type MushiReporterReport, type MushiReputationResult, type MushiRewardsConfig, type MushiRuntimeSdkConfig, type MushiSDKInstance, type MushiSdkVersionInfo, type MushiSelectedElement, type MushiSentryConfig, type MushiSentryContext, type MushiTierResult, type MushiTimelineEntry, type MushiTimelineKind, type MushiUrlMatcher, type MushiWidgetAnchor, type MushiWidgetConfig, type NormalisedException, type OfflineQueue, type PiiScrubberConfig, type PreFilterResult, REGION_ENDPOINTS, type RateLimiter, type RateLimiterConfig, captureEnvironment, createApiClient, createBreadcrumbBuffer, createLogger, createOfflineQueue, createPiiScrubber, createPreFilter, createRateLimiter, getDeviceFingerprintHash, getReporterToken, getSessionId, noopLogger, normaliseThrown, resolveRegionEndpoint, scrubPii };
|
package/dist/index.d.ts
CHANGED
|
@@ -19,43 +19,12 @@ interface MushiConfig {
|
|
|
19
19
|
integrations?: MushiIntegrationsConfig;
|
|
20
20
|
offline?: MushiOfflineConfig;
|
|
21
21
|
rewards?: MushiRewardsConfig;
|
|
22
|
-
/**
|
|
23
|
-
* Sentry-spec-1.0 hook fired AFTER preFilter / on-device classifier /
|
|
24
|
-
* rate-limit gates pass and BEFORE the report is sent or queued.
|
|
25
|
-
* Return:
|
|
26
|
-
* - the report (possibly modified) → submit as-is
|
|
27
|
-
* - a Promise<MushiReport> → await, then submit
|
|
28
|
-
* - `null` → drop the report silently (no `report:sent`/`:failed` event)
|
|
29
|
-
*
|
|
30
|
-
* Use this for app-level redaction of sensitive metadata, hard-coded
|
|
31
|
-
* tag overrides, or last-mile category routing. Errors thrown inside
|
|
32
|
-
* the hook are caught and logged; the report still ships unchanged so
|
|
33
|
-
* a buggy hook never silently swallows feedback.
|
|
34
|
-
*
|
|
35
|
-
* Mirrors Sentry's [SDK feedback spec §4](https://develop.sentry.dev/sdk/telemetry/feedbacks/)
|
|
36
|
-
* `beforeSendFeedback` callback.
|
|
37
|
-
*/
|
|
38
|
-
beforeSendFeedback?: (report: MushiReport) => MushiReport | Promise<MushiReport | null> | null;
|
|
39
|
-
/**
|
|
40
|
-
* Sentry-spec-1.0 callback fired exactly once on `init()` after the
|
|
41
|
-
* SDK detects that the previous browser session ended in a crash
|
|
42
|
-
* (uncaught exception, unhandled rejection, or hard navigate during
|
|
43
|
-
* unfinished submit). Use it to surface a "Tell us what went wrong?"
|
|
44
|
-
* prompt to the user — the SDK does NOT auto-open the widget so the
|
|
45
|
-
* host app can decide on copy and timing.
|
|
46
|
-
*
|
|
47
|
-
* The promise resolves with `true` when a crash was detected, `false`
|
|
48
|
-
* when the previous run ended cleanly, and `null` when the SDK can't
|
|
49
|
-
* tell (typically: localStorage unavailable, or first-ever load).
|
|
50
|
-
*
|
|
51
|
-
* Mirrors Sentry's [SDK feedback spec §6](https://develop.sentry.dev/sdk/telemetry/feedbacks/)
|
|
52
|
-
* `onCrashedLastRun` hook.
|
|
53
|
-
*/
|
|
54
|
-
onCrashedLastRun?: (info: {
|
|
55
|
-
crashed: boolean | null;
|
|
56
|
-
}) => void;
|
|
57
22
|
debug?: boolean;
|
|
58
23
|
enabled?: boolean;
|
|
24
|
+
/** Hook called before a report is sent. Return null to cancel, or return the (possibly modified) report. */
|
|
25
|
+
beforeSendFeedback?: (report: MushiReport) => MushiReport | null | Promise<MushiReport | null>;
|
|
26
|
+
/** Called once if the app crashed during the previous session. */
|
|
27
|
+
onCrashedLastRun?: (crashed: boolean) => void;
|
|
59
28
|
}
|
|
60
29
|
interface MushiSentryConfig {
|
|
61
30
|
dsn?: string;
|
|
@@ -78,9 +47,17 @@ interface MushiWidgetConfig {
|
|
|
78
47
|
zIndex?: number;
|
|
79
48
|
/**
|
|
80
49
|
* Controls how, or whether, the default trigger is injected.
|
|
81
|
-
* `auto`
|
|
50
|
+
* `auto` — historical floating stamp FAB.
|
|
51
|
+
* `banner` — slim full-width header strip (recommended default; less obtrusive
|
|
52
|
+
* than a FAB and visible even when the SDK launcher is `hide()`'d).
|
|
53
|
+
* Pair with `bannerConfig` to customise appearance.
|
|
54
|
+
*/
|
|
55
|
+
trigger?: 'auto' | 'banner' | 'edge-tab' | 'attach' | 'manual' | 'hidden';
|
|
56
|
+
/**
|
|
57
|
+
* Configuration for the header-banner launcher mode.
|
|
58
|
+
* Only applies when `trigger === 'banner'`.
|
|
82
59
|
*/
|
|
83
|
-
|
|
60
|
+
bannerConfig?: MushiBannerConfig;
|
|
84
61
|
/** CSS selector used when `trigger` is `attach`. */
|
|
85
62
|
attachToSelector?: string;
|
|
86
63
|
/**
|
|
@@ -109,13 +86,65 @@ interface MushiWidgetConfig {
|
|
|
109
86
|
*/
|
|
110
87
|
betaMode?: MushiBetaModeConfig;
|
|
111
88
|
/**
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
89
|
+
* Absolute base URL of the Mushi admin console (e.g. `https://mushi.example.com`).
|
|
90
|
+
* When set, the success step surfaces a one-tap link to the user's own report
|
|
91
|
+
* on the console so they can watch the status change in real time. Without
|
|
92
|
+
* this the success step still confirms submission but cannot deep-link.
|
|
93
|
+
*
|
|
94
|
+
* This is intentionally separate from the API endpoint — production apps
|
|
95
|
+
* usually have the API on `api.mushi.example.com` and the console on
|
|
96
|
+
* `app.mushi.example.com`.
|
|
97
|
+
*/
|
|
98
|
+
dashboardUrl?: string;
|
|
99
|
+
/**
|
|
100
|
+
* Override the SLA copy shown in the success step's "what happens next"
|
|
101
|
+
* line. Defaults to "We aim to review within 48h". Set to an empty string
|
|
102
|
+
* to hide the line entirely (e.g. internal-only deployments where SLA
|
|
103
|
+
* messaging would be over-promising).
|
|
104
|
+
*/
|
|
105
|
+
responseSlaLabel?: string;
|
|
106
|
+
/**
|
|
107
|
+
* Show a first-class "Feature request" card at the top of the category
|
|
108
|
+
* step. Defaults to true. Set to false for production-only deployments
|
|
109
|
+
* where you don't want to invite feature ideas through the widget.
|
|
110
|
+
* Internally this maps to `category='other'` with
|
|
111
|
+
* `user_category='Feature request'` so no DB migration is needed.
|
|
116
112
|
*/
|
|
113
|
+
featureRequestCard?: boolean;
|
|
114
|
+
/** Override the localised label for the feature-request card. */
|
|
115
|
+
featureRequestLabel?: string;
|
|
116
|
+
/** Override the helper text shown under the feature-request card. */
|
|
117
|
+
featureRequestDescription?: string;
|
|
118
|
+
/** Minimum description character count before the submit button enables. */
|
|
117
119
|
minDescriptionLength?: number;
|
|
118
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Configuration for the `trigger: 'banner'` header-strip launcher.
|
|
123
|
+
*
|
|
124
|
+
* The banner renders as a slim, full-width strip pinned to the top of the
|
|
125
|
+
* viewport (or bottom if `position === 'bottom'`). It is styled to match the
|
|
126
|
+
* app's brand accent and dismissed per-session via a ✕ button.
|
|
127
|
+
*
|
|
128
|
+
* Variants
|
|
129
|
+
* --------
|
|
130
|
+
* `neon` — lime / electric-green strip (high contrast, dev / beta tool feel).
|
|
131
|
+
* `brand` — uses the Mushi vermillion accent (editorial, app-quality feel).
|
|
132
|
+
* `subtle` — near-invisible hairline with muted text (least disruptive).
|
|
133
|
+
*/
|
|
134
|
+
interface MushiBannerConfig {
|
|
135
|
+
/** Visual style of the banner strip. Defaults to `'brand'`. */
|
|
136
|
+
variant?: 'neon' | 'brand' | 'subtle';
|
|
137
|
+
/** 'top' pins the banner below any existing sticky headers; 'bottom' pins above bottom navs. Defaults to 'top'. */
|
|
138
|
+
position?: 'top' | 'bottom';
|
|
139
|
+
/** Override the call-to-action text in the banner. Defaults to 'Report a bug'. */
|
|
140
|
+
bugCta?: string;
|
|
141
|
+
/** Show a "✨ Request a feature" button alongside the bug button. Defaults to true. */
|
|
142
|
+
featureCta?: boolean;
|
|
143
|
+
/** Override the feature-request button label. */
|
|
144
|
+
featureCtaLabel?: string;
|
|
145
|
+
/** CSS z-index of the banner element. Defaults to the widget's configured zIndex. */
|
|
146
|
+
zIndex?: number;
|
|
147
|
+
}
|
|
119
148
|
interface MushiBetaModeConfig {
|
|
120
149
|
enabled?: boolean;
|
|
121
150
|
/** Display name of the app shown in the beta strip. Defaults to 'This app'. */
|
|
@@ -240,6 +269,17 @@ interface MushiPrivacyConfig {
|
|
|
240
269
|
maskSelectors?: string[];
|
|
241
270
|
/** DOM subtrees to remove from screenshots before upload. */
|
|
242
271
|
blockSelectors?: string[];
|
|
272
|
+
/**
|
|
273
|
+
* CSS selectors whose matching elements are blacked-out (filled with an
|
|
274
|
+
* opaque black rectangle) in screenshots before upload. Intended for
|
|
275
|
+
* sensitive fields that should never appear in any form — passwords, PII,
|
|
276
|
+
* financial data. Applied in addition to `maskSelectors`.
|
|
277
|
+
*
|
|
278
|
+
* Default: `['input[type="password"]', '[data-mushi-redact]']`
|
|
279
|
+
*
|
|
280
|
+
* To disable the default redaction, pass an empty array.
|
|
281
|
+
*/
|
|
282
|
+
redactSelectors?: string[];
|
|
243
283
|
/** Let reporters remove an attached screenshot before submitting. Defaults to true. */
|
|
244
284
|
allowUserRemoveScreenshot?: boolean;
|
|
245
285
|
}
|
|
@@ -249,6 +289,38 @@ interface MushiProactiveConfig {
|
|
|
249
289
|
longTask?: boolean;
|
|
250
290
|
apiCascade?: boolean | MushiApiCascadeConfig;
|
|
251
291
|
cooldown?: MushiCooldownConfig;
|
|
292
|
+
/**
|
|
293
|
+
* Beta-mode nudge: fire after the user has been on the same route for
|
|
294
|
+
* `thresholdMs` continuous milliseconds (default 5min). Pass `true` to
|
|
295
|
+
* accept the default threshold, or a config object to override. Use
|
|
296
|
+
* conservatively — set the per-session cap in `cooldown` to avoid
|
|
297
|
+
* nag fatigue.
|
|
298
|
+
*/
|
|
299
|
+
pageDwell?: boolean | MushiPageDwellConfig;
|
|
300
|
+
/**
|
|
301
|
+
* One-shot welcome prompt for first-time visitors. Fires `delayMs` after
|
|
302
|
+
* `Mushi.init` (default 45s) and is suppressed permanently after the
|
|
303
|
+
* first fire via localStorage. Recommended for beta deployments.
|
|
304
|
+
*/
|
|
305
|
+
firstSession?: boolean | MushiFirstSessionConfig;
|
|
306
|
+
}
|
|
307
|
+
interface MushiPageDwellConfig {
|
|
308
|
+
/** Continuous dwell time before firing. Defaults to 5 minutes. */
|
|
309
|
+
thresholdMs?: number;
|
|
310
|
+
/**
|
|
311
|
+
* Route path prefixes (or glob-style patterns with `*`) that suppress the
|
|
312
|
+
* dwell nudge. Auth routes are excluded by default so users aren't prompted
|
|
313
|
+
* during login/signup flows.
|
|
314
|
+
*
|
|
315
|
+
* Default: `['/login', '/logout', '/signup', '/sso/*', '/auth/*']`
|
|
316
|
+
*/
|
|
317
|
+
excludeRoutes?: string[];
|
|
318
|
+
}
|
|
319
|
+
interface MushiFirstSessionConfig {
|
|
320
|
+
/** Delay before firing the welcome nudge. Defaults to 45 seconds. */
|
|
321
|
+
delayMs?: number;
|
|
322
|
+
/** Override the localStorage key used to mark the user as welcomed. */
|
|
323
|
+
storageKey?: string;
|
|
252
324
|
}
|
|
253
325
|
type MushiUrlMatcher = string | RegExp;
|
|
254
326
|
interface MushiApiCascadeConfig {
|
|
@@ -704,32 +776,16 @@ interface MushiPerformanceMetrics {
|
|
|
704
776
|
lcp?: number;
|
|
705
777
|
cls?: number;
|
|
706
778
|
fid?: number;
|
|
707
|
-
/**
|
|
708
|
-
* Interaction to Next Paint — the worst-observed user interaction
|
|
709
|
-
* latency (ms) since SDK init. Replaces FID as a Core Web Vital
|
|
710
|
-
* since March 2024. Captured via `PerformanceObserver({ type: 'event',
|
|
711
|
-
* durationThreshold: 40 })` per the [web-vitals INP spec](https://web.dev/articles/inp).
|
|
712
|
-
*/
|
|
713
779
|
inp?: number;
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
* interaction. Lets the triage UI surface "the slow click was on
|
|
717
|
-
* <button.checkout>" rather than just "1200 ms INP".
|
|
718
|
-
*/
|
|
780
|
+
ttfb?: number;
|
|
781
|
+
longTasks?: number;
|
|
719
782
|
inpAttribution?: {
|
|
720
|
-
/** PerformanceEventTiming.name (`pointerdown`, `keydown`, …). */
|
|
721
783
|
eventType?: string;
|
|
722
|
-
/** Tag + id + first class of the element that triggered the slow event. */
|
|
723
784
|
targetSelector?: string;
|
|
724
|
-
/** Time between the user input and the start of event processing. */
|
|
725
785
|
inputDelay?: number;
|
|
726
|
-
/** Time spent running the event handler. */
|
|
727
786
|
processingDuration?: number;
|
|
728
|
-
/** Time between handler end and the next paint. */
|
|
729
787
|
presentationDelay?: number;
|
|
730
788
|
};
|
|
731
|
-
ttfb?: number;
|
|
732
|
-
longTasks?: number;
|
|
733
789
|
}
|
|
734
790
|
interface MushiSelectedElement {
|
|
735
791
|
tagName: string;
|
|
@@ -762,14 +818,7 @@ interface MushiTimelineEntry {
|
|
|
762
818
|
kind: MushiTimelineKind;
|
|
763
819
|
payload: Record<string, unknown>;
|
|
764
820
|
}
|
|
765
|
-
type MushiEventType = 'report:submitted' | 'report:queued' | 'report:sent' | 'report:failed'
|
|
766
|
-
/**
|
|
767
|
-
* Fired when the submitted report has been picked up by a Cursor Cloud
|
|
768
|
-
* Agent and an automated fix is in progress. `data.agentId` is the
|
|
769
|
-
* Cursor agent run ID (bc-…); `data.fixId` is the mushi fix_attempt UUID.
|
|
770
|
-
* Useful for showing a toast: "A Cursor agent is working on your report".
|
|
771
|
-
*/
|
|
772
|
-
| 'report:dispatched' | 'widget:opened' | 'widget:closed' | 'proactive:triggered' | 'proactive:dismissed';
|
|
821
|
+
type MushiEventType = 'report:submitted' | 'report:queued' | 'report:sent' | 'report:failed' | 'widget:opened' | 'widget:closed' | 'proactive:triggered' | 'proactive:dismissed' | 'report:dispatched';
|
|
773
822
|
type MushiEventHandler = (event: {
|
|
774
823
|
type: MushiEventType;
|
|
775
824
|
data?: unknown;
|
|
@@ -786,8 +835,16 @@ interface MushiDiagnosticsResult {
|
|
|
786
835
|
sdkVersion: string;
|
|
787
836
|
}
|
|
788
837
|
interface MushiSDKInstance {
|
|
838
|
+
/**
|
|
839
|
+
* Open the reporter widget. With no options, opens to the category
|
|
840
|
+
* picker so the user can choose between bug categories and the
|
|
841
|
+
* feature-request shortcut. Pass `{ category }` to deep-link into a
|
|
842
|
+
* specific bug intent, or `{ featureRequest: true }` to deep-link into
|
|
843
|
+
* the feature-request description step (skips intent picker).
|
|
844
|
+
*/
|
|
789
845
|
report(options?: {
|
|
790
846
|
category?: MushiReportCategory;
|
|
847
|
+
featureRequest?: boolean;
|
|
791
848
|
}): void;
|
|
792
849
|
on(event: MushiEventType, handler: MushiEventHandler): () => void;
|
|
793
850
|
setUser(user: {
|
|
@@ -888,6 +945,12 @@ interface MushiSDKInstance {
|
|
|
888
945
|
* No-op when rewards are disabled or the user has not opted in.
|
|
889
946
|
*/
|
|
890
947
|
recordActivity(action: string, metadata?: Record<string, unknown>): void;
|
|
948
|
+
/**
|
|
949
|
+
* Briefly animate the bug-report trigger button to draw the user's
|
|
950
|
+
* attention without opening the full widget. Ideal for subtle "feedback
|
|
951
|
+
* welcome" nudges (first-session, beta-onboarding).
|
|
952
|
+
*/
|
|
953
|
+
pulseTrigger(): void;
|
|
891
954
|
}
|
|
892
955
|
interface MushiCaptureExceptionOptions {
|
|
893
956
|
/** Override the default `'bug'` category (e.g. `'slow'` for timeouts). */
|
|
@@ -1339,4 +1402,4 @@ declare function createLogger(options: LoggerOptions): Logger;
|
|
|
1339
1402
|
*/
|
|
1340
1403
|
declare const noopLogger: Logger;
|
|
1341
1404
|
|
|
1342
|
-
export { type ApiClientOptions, type BreadcrumbBuffer, type BreadcrumbBufferOptions, DEFAULT_API_ENDPOINT, type LogEntry, type LogFormat, type LogLevel, type Logger, type LoggerOptions, MUSHI_INTERNAL_HEADER, MUSHI_INTERNAL_INIT_MARKER, type MushiActivityEvent, type MushiApiCascadeConfig, type MushiApiClient, type MushiApiResponse, type MushiBetaChangelogEntry, type MushiBetaModeConfig, type MushiBreadcrumb, type MushiCaptureConfig, type MushiCaptureEventInput, type MushiCaptureExceptionOptions, type MushiConfig, type MushiConsoleEntry, type MushiCooldownConfig, type MushiDiagnosticsResult, type MushiDiscoverInventoryConfig, type MushiDiscoveryEventPayload, type MushiEnvironment, type MushiEventHandler, type MushiEventType, type MushiIntegrationsConfig, type MushiInternalRequestKind, type MushiNetworkEntry, type MushiOfflineConfig, type MushiOnDeviceClassifier, type MushiOnDeviceClassifierInput, type MushiOnDeviceClassifierResult, type MushiPerformanceMetrics, type MushiPreFilterConfig, type MushiPreset, type MushiPrivacyConfig, type MushiProactiveConfig, type MushiRegion, type MushiReport, type MushiReportBuilder, type MushiReportCategory, type MushiReportStatus, type MushiReporterComment, type MushiReporterReport, type MushiReputationResult, type MushiRewardsConfig, type MushiRuntimeSdkConfig, type MushiSDKInstance, type MushiSdkVersionInfo, type MushiSelectedElement, type MushiSentryConfig, type MushiSentryContext, type MushiTierResult, type MushiTimelineEntry, type MushiTimelineKind, type MushiUrlMatcher, type MushiWidgetAnchor, type MushiWidgetConfig, type NormalisedException, type OfflineQueue, type PiiScrubberConfig, type PreFilterResult, REGION_ENDPOINTS, type RateLimiter, type RateLimiterConfig, captureEnvironment, createApiClient, createBreadcrumbBuffer, createLogger, createOfflineQueue, createPiiScrubber, createPreFilter, createRateLimiter, getDeviceFingerprintHash, getReporterToken, getSessionId, noopLogger, normaliseThrown, resolveRegionEndpoint, scrubPii };
|
|
1405
|
+
export { type ApiClientOptions, type BreadcrumbBuffer, type BreadcrumbBufferOptions, DEFAULT_API_ENDPOINT, type LogEntry, type LogFormat, type LogLevel, type Logger, type LoggerOptions, MUSHI_INTERNAL_HEADER, MUSHI_INTERNAL_INIT_MARKER, type MushiActivityEvent, type MushiApiCascadeConfig, type MushiApiClient, type MushiApiResponse, type MushiBannerConfig, type MushiBetaChangelogEntry, type MushiBetaModeConfig, type MushiBreadcrumb, type MushiCaptureConfig, type MushiCaptureEventInput, type MushiCaptureExceptionOptions, type MushiConfig, type MushiConsoleEntry, type MushiCooldownConfig, type MushiDiagnosticsResult, type MushiDiscoverInventoryConfig, type MushiDiscoveryEventPayload, type MushiEnvironment, type MushiEventHandler, type MushiEventType, type MushiIntegrationsConfig, type MushiInternalRequestKind, type MushiNetworkEntry, type MushiOfflineConfig, type MushiOnDeviceClassifier, type MushiOnDeviceClassifierInput, type MushiOnDeviceClassifierResult, type MushiPerformanceMetrics, type MushiPreFilterConfig, type MushiPreset, type MushiPrivacyConfig, type MushiProactiveConfig, type MushiRegion, type MushiReport, type MushiReportBuilder, type MushiReportCategory, type MushiReportStatus, type MushiReporterComment, type MushiReporterReport, type MushiReputationResult, type MushiRewardsConfig, type MushiRuntimeSdkConfig, type MushiSDKInstance, type MushiSdkVersionInfo, type MushiSelectedElement, type MushiSentryConfig, type MushiSentryContext, type MushiTierResult, type MushiTimelineEntry, type MushiTimelineKind, type MushiUrlMatcher, type MushiWidgetAnchor, type MushiWidgetConfig, type NormalisedException, type OfflineQueue, type PiiScrubberConfig, type PreFilterResult, REGION_ENDPOINTS, type RateLimiter, type RateLimiterConfig, captureEnvironment, createApiClient, createBreadcrumbBuffer, createLogger, createOfflineQueue, createPiiScrubber, createPreFilter, createRateLimiter, getDeviceFingerprintHash, getReporterToken, getSessionId, noopLogger, normaliseThrown, resolveRegionEndpoint, scrubPii };
|
package/dist/index.js
CHANGED
|
@@ -50,7 +50,7 @@ function createApiClient(options) {
|
|
|
50
50
|
return {
|
|
51
51
|
ok: false,
|
|
52
52
|
error: {
|
|
53
|
-
code: `HTTP_${response.status}`,
|
|
53
|
+
code: errorBody.error?.code || `HTTP_${response.status}`,
|
|
54
54
|
message: errorBody.error?.message || errorBody.message || `HTTP ${response.status} error`
|
|
55
55
|
}
|
|
56
56
|
};
|
|
@@ -775,6 +775,17 @@ function createOfflineQueue(config = {}) {
|
|
|
775
775
|
}
|
|
776
776
|
sent++;
|
|
777
777
|
} else {
|
|
778
|
+
const permanent = result.error?.code === "HTTP_400" || result.error?.code === "HTTP_422" || result.error?.code === "INGEST_ERROR" || result.error?.code === "VALIDATION_ERROR" || typeof result.error?.message === "string" && /invalid payload|description must be at least|validation/i.test(
|
|
779
|
+
result.error.message
|
|
780
|
+
);
|
|
781
|
+
if (permanent) {
|
|
782
|
+
try {
|
|
783
|
+
if (backend === "indexeddb") await idbDelete(rowId);
|
|
784
|
+
else lsDelete(rowId);
|
|
785
|
+
} catch {
|
|
786
|
+
lsDelete(rowId);
|
|
787
|
+
}
|
|
788
|
+
}
|
|
778
789
|
failed++;
|
|
779
790
|
if (i < batch.length - 1) {
|
|
780
791
|
await sleep2(getBackoffDelay2(i));
|