@mushi-mushi/core 1.12.0 → 1.14.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.d.cts CHANGED
@@ -39,7 +39,16 @@ interface MushiWidgetConfig {
39
39
  * banners. When set, these values win over `position` + numeric `inset`.
40
40
  */
41
41
  anchor?: MushiWidgetAnchor;
42
- theme?: 'auto' | 'light' | 'dark';
42
+ theme?: 'auto' | 'light' | 'dark' | 'inherit';
43
+ /**
44
+ * Override the widget's primary accent colour (default: vermillion #E03C2C).
45
+ * Must be a CSS colour value that has sufficient contrast against both light
46
+ * and dark widget backgrounds. The widget derives a wash + accessible ink
47
+ * colour automatically, so only the base colour is required.
48
+ */
49
+ accent?: string;
50
+ /** Explicit text colour on the accent surface. Auto-computed when omitted. */
51
+ accentText?: string;
43
52
  triggerText?: string;
44
53
  expandedTitle?: string;
45
54
  mode?: 'simple' | 'conversational';
@@ -73,7 +82,20 @@ interface MushiWidgetConfig {
73
82
  environments?: Partial<Record<'production' | 'staging' | 'development', 'always' | 'never' | 'manual'>>;
74
83
  /** Opt-in smart trigger behavior; planned to become the default in a later minor. */
75
84
  smartHide?: boolean | MushiWidgetSmartHideConfig;
76
- draggable?: boolean;
85
+ /**
86
+ * Allow the FAB to be dragged and repositioned by the user.
87
+ * - `true` — drag enabled, persisted to localStorage, snaps to nearest edge on release.
88
+ * - `false` — fixed position (default).
89
+ * - Object — fine-grained control:
90
+ * - `persist` save position per projectId (default true when draggable).
91
+ * - `snapToEdge` snap to the nearest left/right edge on release (default true).
92
+ * - `axis` constrain movement to one axis (`'x'`, `'y'`, or `'both'` default).
93
+ */
94
+ draggable?: boolean | {
95
+ persist?: boolean;
96
+ snapToEdge?: boolean;
97
+ axis?: 'both' | 'x' | 'y';
98
+ };
77
99
  /** Show the tiny "Powered by Mushi vX" footer inside the widget panel. */
78
100
  brandFooter?: boolean;
79
101
  /** How the widget should surface SDK freshness warnings. Defaults to auto. */
@@ -129,6 +151,51 @@ interface MushiWidgetConfig {
129
151
  * avoidSelectors: ['[data-mobile-header]', '#sign-in-cta']
130
152
  */
131
153
  avoidSelectors?: string[];
154
+ /**
155
+ * Override the default five-category picker with a custom category list.
156
+ * When set, the widget renders these categories instead of the built-in
157
+ * `bug / slow / visual / confusing / other` set.
158
+ *
159
+ * Each custom category maps onto one of the five built-in `MushiReportCategory`
160
+ * values via `baseCategory` (defaults to `'other'`). The custom id is
161
+ * preserved as `userCategory` on the report so the Mushi console can filter
162
+ * by it independently of the LLM-assigned `category`.
163
+ *
164
+ * Deep-link helpers (`open`, `openWith`, `report`) accept the custom `id`
165
+ * in addition to the built-in enum values when this option is set.
166
+ *
167
+ * When absent, behaviour is identical to the historical defaults (backward-compatible).
168
+ */
169
+ categories?: MushiCustomCategory[];
170
+ }
171
+ /**
172
+ * Descriptor for a single entry in a host-app custom category list.
173
+ * Passed as `widget.categories` to `Mushi.init()`.
174
+ */
175
+ interface MushiCustomCategory {
176
+ /** Unique identifier used in `openWith(id)` / `report({ category: id })`. */
177
+ id: string;
178
+ /** Human-readable label shown in the category picker step. */
179
+ label: string;
180
+ /** Optional helper text shown beneath the label. */
181
+ description?: string;
182
+ /**
183
+ * Localised intent options displayed on the second step ("What happened?").
184
+ * When omitted, the widget skips the intent step and goes straight to
185
+ * the description.
186
+ */
187
+ intents?: string[];
188
+ /**
189
+ * Emoji or single-character icon rendered next to the label in the picker.
190
+ * Falls back to a neutral bubble when absent.
191
+ */
192
+ icon?: string;
193
+ /**
194
+ * Which built-in `MushiReportCategory` value this custom category maps to
195
+ * for server-side classification. Defaults to `'other'`.
196
+ * The custom `id` is always preserved in `report.userCategory`.
197
+ */
198
+ baseCategory?: MushiReportCategory;
132
199
  }
133
200
  /** Optional flat link in the rich banner action row (admin-console BetaBanner style). */
134
201
  interface MushiBannerLink {
@@ -543,6 +610,13 @@ interface MushiReport {
543
610
  id: string;
544
611
  projectId: string;
545
612
  category: MushiReportCategory;
613
+ /**
614
+ * Custom category identifier set by the host app via `widget.categories`.
615
+ * Preserved as `reports.user_category` on the server so the Mushi console
616
+ * can filter by it independently of the LLM-assigned `category`.
617
+ * Not set when the host uses the default built-in category set.
618
+ */
619
+ userCategory?: string;
546
620
  description: string;
547
621
  userIntent?: string;
548
622
  environment: MushiEnvironment;
@@ -957,9 +1031,12 @@ interface MushiSDKInstance {
957
1031
  * feature-request shortcut. Pass `{ category }` to deep-link into a
958
1032
  * specific bug intent, or `{ featureRequest: true }` to deep-link into
959
1033
  * the feature-request description step (skips intent picker).
1034
+ *
1035
+ * When `widget.categories` is configured, `category` also accepts a
1036
+ * custom category `id` from that list.
960
1037
  */
961
1038
  report(options?: {
962
- category?: MushiReportCategory;
1039
+ category?: MushiReportCategory | string;
963
1040
  featureRequest?: boolean;
964
1041
  }): void;
965
1042
  on(event: MushiEventType, handler: MushiEventHandler): () => void;
@@ -976,7 +1053,12 @@ interface MushiSDKInstance {
976
1053
  }): void;
977
1054
  isOpen(): boolean;
978
1055
  open(): void;
979
- openWith(category: MushiReportCategory): void;
1056
+ /**
1057
+ * Open the widget deep-linked to a specific category. Accepts a built-in
1058
+ * `MushiReportCategory` value or a custom category `id` when
1059
+ * `widget.categories` is configured.
1060
+ */
1061
+ openWith(category: MushiReportCategory | string): void;
980
1062
  show(): void;
981
1063
  hide(): void;
982
1064
  attachTo(selectorOrElement: string | Element, options?: MushiWidgetConfig): () => void;
@@ -1239,6 +1321,38 @@ interface MushiApiClient {
1239
1321
  project_name: string;
1240
1322
  };
1241
1323
  }>>;
1324
+ /** Link the anonymous reporter_token_hash to the caller's mushi_testers row. */
1325
+ sendMagicLink(email: string): Promise<MushiApiResponse<{
1326
+ ok: boolean;
1327
+ }>>;
1328
+ linkReporterToken(reporterTokenHash: string, jwt: string): Promise<MushiApiResponse<{
1329
+ ok: boolean;
1330
+ linked: number;
1331
+ }>>;
1332
+ /** All reports filed by the signed-in tester, across all projects. */
1333
+ getCrossAppReports(jwt: string, opts?: {
1334
+ limit?: number;
1335
+ offset?: number;
1336
+ }): Promise<MushiApiResponse<{
1337
+ reports: MushiCrossAppReport[];
1338
+ }>>;
1339
+ /** The signed-in tester's global rank + points. */
1340
+ getMyReputation(jwt: string): Promise<MushiApiResponse<{
1341
+ reputation: MushiTesterReputation | null;
1342
+ }>>;
1343
+ /** Top-N global tester leaderboard (no auth required). */
1344
+ getPublicLeaderboard(limit?: number): Promise<MushiApiResponse<{
1345
+ leaderboard: MushiLeaderboardEntry[];
1346
+ }>>;
1347
+ /** Whether the caller has a mushi_testers row. */
1348
+ getTesterStatus(jwt: string): Promise<MushiApiResponse<{
1349
+ is_tester: boolean;
1350
+ tester: {
1351
+ id: string;
1352
+ public_handle: string | null;
1353
+ display_name: string | null;
1354
+ } | null;
1355
+ }>>;
1242
1356
  }
1243
1357
  /**
1244
1358
  * Wire shape of a single discovery event sent by the SDK to
@@ -1314,6 +1428,38 @@ interface MushiHallOfFameEntry {
1314
1428
  points_30d: number;
1315
1429
  total_points: number;
1316
1430
  }
1431
+ /** A report filed by the current tester, across any project. */
1432
+ interface MushiCrossAppReport {
1433
+ id: string;
1434
+ short_id: string | null;
1435
+ title: string | null;
1436
+ category: string;
1437
+ status: string;
1438
+ created_at: string;
1439
+ updated_at: string;
1440
+ project_id: string | null;
1441
+ app_name: string | null;
1442
+ app_slug: string | null;
1443
+ }
1444
+ /** A single entry in the global tester leaderboard. */
1445
+ interface MushiLeaderboardEntry {
1446
+ tester_id: string;
1447
+ public_handle: string | null;
1448
+ display_name: string | null;
1449
+ rank: number;
1450
+ points_30d: number;
1451
+ total_points: number;
1452
+ badge_slug?: string | null;
1453
+ }
1454
+ /** The caller's global reputation snapshot. */
1455
+ interface MushiTesterReputation {
1456
+ tester_id: string;
1457
+ public_handle: string | null;
1458
+ display_name: string | null;
1459
+ rank: number | null;
1460
+ points_30d: number;
1461
+ total_points: number;
1462
+ }
1317
1463
 
1318
1464
  interface ApiClientOptions {
1319
1465
  projectId: string;
@@ -1329,7 +1475,7 @@ interface ApiClientOptions {
1329
1475
  declare const DEFAULT_API_ENDPOINT = "https://dxptnwrhwsqckaftyymj.supabase.co/functions/v1/api";
1330
1476
  declare const MUSHI_INTERNAL_HEADER = "X-Mushi-Internal";
1331
1477
  declare const MUSHI_INTERNAL_INIT_MARKER = "__mushiInternal";
1332
- type MushiInternalRequestKind = 'sdk-config' | 'report-submit' | 'report-status' | 'reporter-poll' | 'diagnose' | 'discovery';
1478
+ type MushiInternalRequestKind = 'sdk-config' | 'report-submit' | 'report-status' | 'reporter-poll' | 'diagnose' | 'discovery' | 'community';
1333
1479
  declare function createApiClient(options: ApiClientOptions): MushiApiClient;
1334
1480
 
1335
1481
  /**
@@ -1649,4 +1795,4 @@ declare function createLogger(options: LoggerOptions): Logger;
1649
1795
  */
1650
1796
  declare const noopLogger: Logger;
1651
1797
 
1652
- export { type ApiClientOptions, type BreadcrumbBuffer, type BreadcrumbBufferOptions, DEFAULT_API_ENDPOINT, type LogEntry, type LogFormat, type LogLevel, type Logger, type LoggerOptions, MAX_REPORT_PAYLOAD_BYTES, MAX_SCREENSHOT_DATA_URL_BYTES, MUSHI_INTERNAL_HEADER, MUSHI_INTERNAL_INIT_MARKER, type MushiActivityEvent, type MushiApiCascadeConfig, type MushiApiClient, type MushiApiResponse, type MushiBannerConfig, type MushiBannerLink, 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 MushiHallOfFameEntry, 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 MushiTracePropagationConfig, type MushiUrlMatcher, type MushiWidgetAnchor, type MushiWidgetConfig, type NormalisedException, type OfflineQueue, type PayloadGuardResult, type PiiScrubberConfig, type PreFilterResult, REGION_ENDPOINTS, type RateLimiter, type RateLimiterConfig, captureEnvironment, checkReportPayloadSize, createApiClient, createBreadcrumbBuffer, createLogger, createOfflineQueue, createPiiScrubber, createPreFilter, createRateLimiter, estimateJsonBytes, formatBytes, getDeviceFingerprintHash, getReporterToken, getSessionId, newUuid, noopLogger, normaliseThrown, resolveRegionEndpoint, scrubPii };
1798
+ export { type ApiClientOptions, type BreadcrumbBuffer, type BreadcrumbBufferOptions, DEFAULT_API_ENDPOINT, type LogEntry, type LogFormat, type LogLevel, type Logger, type LoggerOptions, MAX_REPORT_PAYLOAD_BYTES, MAX_SCREENSHOT_DATA_URL_BYTES, MUSHI_INTERNAL_HEADER, MUSHI_INTERNAL_INIT_MARKER, type MushiActivityEvent, type MushiApiCascadeConfig, type MushiApiClient, type MushiApiResponse, type MushiBannerConfig, type MushiBannerLink, type MushiBetaChangelogEntry, type MushiBetaModeConfig, type MushiBreadcrumb, type MushiCaptureConfig, type MushiCaptureEventInput, type MushiCaptureExceptionOptions, type MushiConfig, type MushiConsoleEntry, type MushiCooldownConfig, type MushiCrossAppReport, type MushiCustomCategory, type MushiDiagnosticsResult, type MushiDiscoverInventoryConfig, type MushiDiscoveryEventPayload, type MushiEnvironment, type MushiEventHandler, type MushiEventType, type MushiHallOfFameEntry, type MushiIntegrationsConfig, type MushiInternalRequestKind, type MushiLeaderboardEntry, 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 MushiTesterReputation, type MushiTierResult, type MushiTimelineEntry, type MushiTimelineKind, type MushiTracePropagationConfig, type MushiUrlMatcher, type MushiWidgetAnchor, type MushiWidgetConfig, type NormalisedException, type OfflineQueue, type PayloadGuardResult, type PiiScrubberConfig, type PreFilterResult, REGION_ENDPOINTS, type RateLimiter, type RateLimiterConfig, captureEnvironment, checkReportPayloadSize, createApiClient, createBreadcrumbBuffer, createLogger, createOfflineQueue, createPiiScrubber, createPreFilter, createRateLimiter, estimateJsonBytes, formatBytes, getDeviceFingerprintHash, getReporterToken, getSessionId, newUuid, noopLogger, normaliseThrown, resolveRegionEndpoint, scrubPii };
package/dist/index.d.ts CHANGED
@@ -39,7 +39,16 @@ interface MushiWidgetConfig {
39
39
  * banners. When set, these values win over `position` + numeric `inset`.
40
40
  */
41
41
  anchor?: MushiWidgetAnchor;
42
- theme?: 'auto' | 'light' | 'dark';
42
+ theme?: 'auto' | 'light' | 'dark' | 'inherit';
43
+ /**
44
+ * Override the widget's primary accent colour (default: vermillion #E03C2C).
45
+ * Must be a CSS colour value that has sufficient contrast against both light
46
+ * and dark widget backgrounds. The widget derives a wash + accessible ink
47
+ * colour automatically, so only the base colour is required.
48
+ */
49
+ accent?: string;
50
+ /** Explicit text colour on the accent surface. Auto-computed when omitted. */
51
+ accentText?: string;
43
52
  triggerText?: string;
44
53
  expandedTitle?: string;
45
54
  mode?: 'simple' | 'conversational';
@@ -73,7 +82,20 @@ interface MushiWidgetConfig {
73
82
  environments?: Partial<Record<'production' | 'staging' | 'development', 'always' | 'never' | 'manual'>>;
74
83
  /** Opt-in smart trigger behavior; planned to become the default in a later minor. */
75
84
  smartHide?: boolean | MushiWidgetSmartHideConfig;
76
- draggable?: boolean;
85
+ /**
86
+ * Allow the FAB to be dragged and repositioned by the user.
87
+ * - `true` — drag enabled, persisted to localStorage, snaps to nearest edge on release.
88
+ * - `false` — fixed position (default).
89
+ * - Object — fine-grained control:
90
+ * - `persist` save position per projectId (default true when draggable).
91
+ * - `snapToEdge` snap to the nearest left/right edge on release (default true).
92
+ * - `axis` constrain movement to one axis (`'x'`, `'y'`, or `'both'` default).
93
+ */
94
+ draggable?: boolean | {
95
+ persist?: boolean;
96
+ snapToEdge?: boolean;
97
+ axis?: 'both' | 'x' | 'y';
98
+ };
77
99
  /** Show the tiny "Powered by Mushi vX" footer inside the widget panel. */
78
100
  brandFooter?: boolean;
79
101
  /** How the widget should surface SDK freshness warnings. Defaults to auto. */
@@ -129,6 +151,51 @@ interface MushiWidgetConfig {
129
151
  * avoidSelectors: ['[data-mobile-header]', '#sign-in-cta']
130
152
  */
131
153
  avoidSelectors?: string[];
154
+ /**
155
+ * Override the default five-category picker with a custom category list.
156
+ * When set, the widget renders these categories instead of the built-in
157
+ * `bug / slow / visual / confusing / other` set.
158
+ *
159
+ * Each custom category maps onto one of the five built-in `MushiReportCategory`
160
+ * values via `baseCategory` (defaults to `'other'`). The custom id is
161
+ * preserved as `userCategory` on the report so the Mushi console can filter
162
+ * by it independently of the LLM-assigned `category`.
163
+ *
164
+ * Deep-link helpers (`open`, `openWith`, `report`) accept the custom `id`
165
+ * in addition to the built-in enum values when this option is set.
166
+ *
167
+ * When absent, behaviour is identical to the historical defaults (backward-compatible).
168
+ */
169
+ categories?: MushiCustomCategory[];
170
+ }
171
+ /**
172
+ * Descriptor for a single entry in a host-app custom category list.
173
+ * Passed as `widget.categories` to `Mushi.init()`.
174
+ */
175
+ interface MushiCustomCategory {
176
+ /** Unique identifier used in `openWith(id)` / `report({ category: id })`. */
177
+ id: string;
178
+ /** Human-readable label shown in the category picker step. */
179
+ label: string;
180
+ /** Optional helper text shown beneath the label. */
181
+ description?: string;
182
+ /**
183
+ * Localised intent options displayed on the second step ("What happened?").
184
+ * When omitted, the widget skips the intent step and goes straight to
185
+ * the description.
186
+ */
187
+ intents?: string[];
188
+ /**
189
+ * Emoji or single-character icon rendered next to the label in the picker.
190
+ * Falls back to a neutral bubble when absent.
191
+ */
192
+ icon?: string;
193
+ /**
194
+ * Which built-in `MushiReportCategory` value this custom category maps to
195
+ * for server-side classification. Defaults to `'other'`.
196
+ * The custom `id` is always preserved in `report.userCategory`.
197
+ */
198
+ baseCategory?: MushiReportCategory;
132
199
  }
133
200
  /** Optional flat link in the rich banner action row (admin-console BetaBanner style). */
134
201
  interface MushiBannerLink {
@@ -543,6 +610,13 @@ interface MushiReport {
543
610
  id: string;
544
611
  projectId: string;
545
612
  category: MushiReportCategory;
613
+ /**
614
+ * Custom category identifier set by the host app via `widget.categories`.
615
+ * Preserved as `reports.user_category` on the server so the Mushi console
616
+ * can filter by it independently of the LLM-assigned `category`.
617
+ * Not set when the host uses the default built-in category set.
618
+ */
619
+ userCategory?: string;
546
620
  description: string;
547
621
  userIntent?: string;
548
622
  environment: MushiEnvironment;
@@ -957,9 +1031,12 @@ interface MushiSDKInstance {
957
1031
  * feature-request shortcut. Pass `{ category }` to deep-link into a
958
1032
  * specific bug intent, or `{ featureRequest: true }` to deep-link into
959
1033
  * the feature-request description step (skips intent picker).
1034
+ *
1035
+ * When `widget.categories` is configured, `category` also accepts a
1036
+ * custom category `id` from that list.
960
1037
  */
961
1038
  report(options?: {
962
- category?: MushiReportCategory;
1039
+ category?: MushiReportCategory | string;
963
1040
  featureRequest?: boolean;
964
1041
  }): void;
965
1042
  on(event: MushiEventType, handler: MushiEventHandler): () => void;
@@ -976,7 +1053,12 @@ interface MushiSDKInstance {
976
1053
  }): void;
977
1054
  isOpen(): boolean;
978
1055
  open(): void;
979
- openWith(category: MushiReportCategory): void;
1056
+ /**
1057
+ * Open the widget deep-linked to a specific category. Accepts a built-in
1058
+ * `MushiReportCategory` value or a custom category `id` when
1059
+ * `widget.categories` is configured.
1060
+ */
1061
+ openWith(category: MushiReportCategory | string): void;
980
1062
  show(): void;
981
1063
  hide(): void;
982
1064
  attachTo(selectorOrElement: string | Element, options?: MushiWidgetConfig): () => void;
@@ -1239,6 +1321,38 @@ interface MushiApiClient {
1239
1321
  project_name: string;
1240
1322
  };
1241
1323
  }>>;
1324
+ /** Link the anonymous reporter_token_hash to the caller's mushi_testers row. */
1325
+ sendMagicLink(email: string): Promise<MushiApiResponse<{
1326
+ ok: boolean;
1327
+ }>>;
1328
+ linkReporterToken(reporterTokenHash: string, jwt: string): Promise<MushiApiResponse<{
1329
+ ok: boolean;
1330
+ linked: number;
1331
+ }>>;
1332
+ /** All reports filed by the signed-in tester, across all projects. */
1333
+ getCrossAppReports(jwt: string, opts?: {
1334
+ limit?: number;
1335
+ offset?: number;
1336
+ }): Promise<MushiApiResponse<{
1337
+ reports: MushiCrossAppReport[];
1338
+ }>>;
1339
+ /** The signed-in tester's global rank + points. */
1340
+ getMyReputation(jwt: string): Promise<MushiApiResponse<{
1341
+ reputation: MushiTesterReputation | null;
1342
+ }>>;
1343
+ /** Top-N global tester leaderboard (no auth required). */
1344
+ getPublicLeaderboard(limit?: number): Promise<MushiApiResponse<{
1345
+ leaderboard: MushiLeaderboardEntry[];
1346
+ }>>;
1347
+ /** Whether the caller has a mushi_testers row. */
1348
+ getTesterStatus(jwt: string): Promise<MushiApiResponse<{
1349
+ is_tester: boolean;
1350
+ tester: {
1351
+ id: string;
1352
+ public_handle: string | null;
1353
+ display_name: string | null;
1354
+ } | null;
1355
+ }>>;
1242
1356
  }
1243
1357
  /**
1244
1358
  * Wire shape of a single discovery event sent by the SDK to
@@ -1314,6 +1428,38 @@ interface MushiHallOfFameEntry {
1314
1428
  points_30d: number;
1315
1429
  total_points: number;
1316
1430
  }
1431
+ /** A report filed by the current tester, across any project. */
1432
+ interface MushiCrossAppReport {
1433
+ id: string;
1434
+ short_id: string | null;
1435
+ title: string | null;
1436
+ category: string;
1437
+ status: string;
1438
+ created_at: string;
1439
+ updated_at: string;
1440
+ project_id: string | null;
1441
+ app_name: string | null;
1442
+ app_slug: string | null;
1443
+ }
1444
+ /** A single entry in the global tester leaderboard. */
1445
+ interface MushiLeaderboardEntry {
1446
+ tester_id: string;
1447
+ public_handle: string | null;
1448
+ display_name: string | null;
1449
+ rank: number;
1450
+ points_30d: number;
1451
+ total_points: number;
1452
+ badge_slug?: string | null;
1453
+ }
1454
+ /** The caller's global reputation snapshot. */
1455
+ interface MushiTesterReputation {
1456
+ tester_id: string;
1457
+ public_handle: string | null;
1458
+ display_name: string | null;
1459
+ rank: number | null;
1460
+ points_30d: number;
1461
+ total_points: number;
1462
+ }
1317
1463
 
1318
1464
  interface ApiClientOptions {
1319
1465
  projectId: string;
@@ -1329,7 +1475,7 @@ interface ApiClientOptions {
1329
1475
  declare const DEFAULT_API_ENDPOINT = "https://dxptnwrhwsqckaftyymj.supabase.co/functions/v1/api";
1330
1476
  declare const MUSHI_INTERNAL_HEADER = "X-Mushi-Internal";
1331
1477
  declare const MUSHI_INTERNAL_INIT_MARKER = "__mushiInternal";
1332
- type MushiInternalRequestKind = 'sdk-config' | 'report-submit' | 'report-status' | 'reporter-poll' | 'diagnose' | 'discovery';
1478
+ type MushiInternalRequestKind = 'sdk-config' | 'report-submit' | 'report-status' | 'reporter-poll' | 'diagnose' | 'discovery' | 'community';
1333
1479
  declare function createApiClient(options: ApiClientOptions): MushiApiClient;
1334
1480
 
1335
1481
  /**
@@ -1649,4 +1795,4 @@ declare function createLogger(options: LoggerOptions): Logger;
1649
1795
  */
1650
1796
  declare const noopLogger: Logger;
1651
1797
 
1652
- export { type ApiClientOptions, type BreadcrumbBuffer, type BreadcrumbBufferOptions, DEFAULT_API_ENDPOINT, type LogEntry, type LogFormat, type LogLevel, type Logger, type LoggerOptions, MAX_REPORT_PAYLOAD_BYTES, MAX_SCREENSHOT_DATA_URL_BYTES, MUSHI_INTERNAL_HEADER, MUSHI_INTERNAL_INIT_MARKER, type MushiActivityEvent, type MushiApiCascadeConfig, type MushiApiClient, type MushiApiResponse, type MushiBannerConfig, type MushiBannerLink, 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 MushiHallOfFameEntry, 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 MushiTracePropagationConfig, type MushiUrlMatcher, type MushiWidgetAnchor, type MushiWidgetConfig, type NormalisedException, type OfflineQueue, type PayloadGuardResult, type PiiScrubberConfig, type PreFilterResult, REGION_ENDPOINTS, type RateLimiter, type RateLimiterConfig, captureEnvironment, checkReportPayloadSize, createApiClient, createBreadcrumbBuffer, createLogger, createOfflineQueue, createPiiScrubber, createPreFilter, createRateLimiter, estimateJsonBytes, formatBytes, getDeviceFingerprintHash, getReporterToken, getSessionId, newUuid, noopLogger, normaliseThrown, resolveRegionEndpoint, scrubPii };
1798
+ export { type ApiClientOptions, type BreadcrumbBuffer, type BreadcrumbBufferOptions, DEFAULT_API_ENDPOINT, type LogEntry, type LogFormat, type LogLevel, type Logger, type LoggerOptions, MAX_REPORT_PAYLOAD_BYTES, MAX_SCREENSHOT_DATA_URL_BYTES, MUSHI_INTERNAL_HEADER, MUSHI_INTERNAL_INIT_MARKER, type MushiActivityEvent, type MushiApiCascadeConfig, type MushiApiClient, type MushiApiResponse, type MushiBannerConfig, type MushiBannerLink, type MushiBetaChangelogEntry, type MushiBetaModeConfig, type MushiBreadcrumb, type MushiCaptureConfig, type MushiCaptureEventInput, type MushiCaptureExceptionOptions, type MushiConfig, type MushiConsoleEntry, type MushiCooldownConfig, type MushiCrossAppReport, type MushiCustomCategory, type MushiDiagnosticsResult, type MushiDiscoverInventoryConfig, type MushiDiscoveryEventPayload, type MushiEnvironment, type MushiEventHandler, type MushiEventType, type MushiHallOfFameEntry, type MushiIntegrationsConfig, type MushiInternalRequestKind, type MushiLeaderboardEntry, 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 MushiTesterReputation, type MushiTierResult, type MushiTimelineEntry, type MushiTimelineKind, type MushiTracePropagationConfig, type MushiUrlMatcher, type MushiWidgetAnchor, type MushiWidgetConfig, type NormalisedException, type OfflineQueue, type PayloadGuardResult, type PiiScrubberConfig, type PreFilterResult, REGION_ENDPOINTS, type RateLimiter, type RateLimiterConfig, captureEnvironment, checkReportPayloadSize, createApiClient, createBreadcrumbBuffer, createLogger, createOfflineQueue, createPiiScrubber, createPreFilter, createRateLimiter, estimateJsonBytes, formatBytes, getDeviceFingerprintHash, getReporterToken, getSessionId, newUuid, noopLogger, normaliseThrown, resolveRegionEndpoint, scrubPii };
package/dist/index.js CHANGED
@@ -55,7 +55,7 @@ function createApiClient(options) {
55
55
  maxRetries = DEFAULT_MAX_RETRIES
56
56
  } = options;
57
57
  let baseUrl = apiEndpoint.replace(/\/$/, "");
58
- async function request(method, path, body, retries = maxRetries, internalKind) {
58
+ async function request(method, path, body, retries = maxRetries, internalKind, extraHeaders) {
59
59
  const url = `${baseUrl}${path}`;
60
60
  const controller = new AbortController();
61
61
  const timer = setTimeout(() => controller.abort(), timeout);
@@ -66,7 +66,8 @@ function createApiClient(options) {
66
66
  "Content-Type": "application/json",
67
67
  "X-Mushi-Api-Key": apiKey,
68
68
  "X-Mushi-Project": projectId,
69
- ...internalKind ? { [MUSHI_INTERNAL_HEADER]: internalKind } : {}
69
+ ...internalKind ? { [MUSHI_INTERNAL_HEADER]: internalKind } : {},
70
+ ...extraHeaders
70
71
  },
71
72
  body: body ? JSON.stringify(body) : void 0,
72
73
  signal: controller.signal,
@@ -79,7 +80,7 @@ function createApiClient(options) {
79
80
  const targetBase = target.replace(/\/v1\/.*$/, "").replace(/\/$/, "");
80
81
  if (targetBase !== baseUrl) {
81
82
  baseUrl = targetBase;
82
- return request(method, path, body, retries - 1, internalKind);
83
+ return request(method, path, body, retries - 1, internalKind, extraHeaders);
83
84
  }
84
85
  }
85
86
  }
@@ -87,7 +88,7 @@ function createApiClient(options) {
87
88
  const errorBody = await response.json().catch(() => ({}));
88
89
  if (response.status >= 500 && retries > 0) {
89
90
  await sleep(getBackoffDelay(maxRetries - retries));
90
- return request(method, path, body, retries - 1, internalKind);
91
+ return request(method, path, body, retries - 1, internalKind, extraHeaders);
91
92
  }
92
93
  return {
93
94
  ok: false,
@@ -295,6 +296,69 @@ function createApiClient(options) {
295
296
  1,
296
297
  "reporter-poll"
297
298
  );
299
+ },
300
+ // ─── Cross-app community (in-widget tester identity) ──────────
301
+ async sendMagicLink(email) {
302
+ return request(
303
+ "POST",
304
+ "/v1/tester/magic-link",
305
+ { email },
306
+ 1,
307
+ "community"
308
+ );
309
+ },
310
+ async linkReporterToken(reporterTokenHash, jwt) {
311
+ return request(
312
+ "POST",
313
+ "/v1/tester/link-reporter",
314
+ { reporter_token_hash: reporterTokenHash },
315
+ 1,
316
+ "community",
317
+ { Authorization: `Bearer ${jwt}` }
318
+ );
319
+ },
320
+ async getCrossAppReports(jwt, opts) {
321
+ const qs = new URLSearchParams();
322
+ if (opts?.limit) qs.set("limit", String(opts.limit));
323
+ if (opts?.offset) qs.set("offset", String(opts.offset));
324
+ const suffix = qs.size ? `?${qs.toString()}` : "";
325
+ return request(
326
+ "GET",
327
+ `/v1/tester/cross-app-reports${suffix}`,
328
+ void 0,
329
+ 1,
330
+ "community",
331
+ { Authorization: `Bearer ${jwt}` }
332
+ );
333
+ },
334
+ async getMyReputation(jwt) {
335
+ return request(
336
+ "GET",
337
+ "/v1/tester/reputation",
338
+ void 0,
339
+ 1,
340
+ "community",
341
+ { Authorization: `Bearer ${jwt}` }
342
+ );
343
+ },
344
+ async getPublicLeaderboard(limit = 20) {
345
+ return request(
346
+ "GET",
347
+ `/v1/public/tester-leaderboard?limit=${limit}`,
348
+ void 0,
349
+ 1,
350
+ "reporter-poll"
351
+ );
352
+ },
353
+ async getTesterStatus(jwt) {
354
+ return request(
355
+ "GET",
356
+ "/v1/me/tester-status",
357
+ void 0,
358
+ 1,
359
+ "community",
360
+ { Authorization: `Bearer ${jwt}` }
361
+ );
298
362
  }
299
363
  };
300
364
  }