@bbearai/core 0.1.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 ADDED
@@ -0,0 +1,102 @@
1
+ # @bugbearai/core
2
+
3
+ Core client and utilities for BugBear QA platform.
4
+
5
+ > **Note:** Most users should install `@bugbearai/react` instead, which includes this package automatically.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @bugbearai/core
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```typescript
16
+ import { createBugBear } from '@bugbearai/core';
17
+
18
+ const bugbear = createBugBear({
19
+ projectId: 'your-project-id',
20
+ getCurrentUser: async () => ({
21
+ id: 'user-123',
22
+ email: 'user@example.com',
23
+ }),
24
+ });
25
+
26
+ // Submit a report
27
+ await bugbear.submitReport({
28
+ type: 'bug',
29
+ description: 'Button does not work',
30
+ severity: 'high',
31
+ });
32
+
33
+ // Check if user is a tester
34
+ const isTester = await bugbear.isTester();
35
+
36
+ // Get assigned test cases
37
+ const assignments = await bugbear.getAssignedTests();
38
+ ```
39
+
40
+ ## API Reference
41
+
42
+ ### createBugBear(config)
43
+
44
+ Creates a BugBear client instance.
45
+
46
+ ### Client Methods
47
+
48
+ | Method | Description |
49
+ |--------|-------------|
50
+ | `submitReport(report)` | Submit a bug report, feedback, or test result |
51
+ | `isTester()` | Check if current user is a registered tester |
52
+ | `isQAEnabled()` | Check if QA mode is enabled for the project |
53
+ | `shouldShowWidget()` | Check if widget should be visible (QA enabled + is tester) |
54
+ | `getTesterInfo()` | Get current tester's info |
55
+ | `getAssignedTests()` | Get test cases assigned to current tester |
56
+ | `trackNavigation(route)` | Track navigation for context |
57
+ | `uploadScreenshot(file)` | Upload a screenshot |
58
+
59
+ ## Types
60
+
61
+ ```typescript
62
+ interface BugBearReport {
63
+ type: 'bug' | 'feedback' | 'suggestion' | 'test_pass' | 'test_fail';
64
+ description: string;
65
+ title?: string;
66
+ severity?: 'critical' | 'high' | 'medium' | 'low';
67
+ screenshots?: string[];
68
+ appContext?: AppContext;
69
+ // ... and more
70
+ }
71
+
72
+ interface TesterInfo {
73
+ id: string;
74
+ name: string;
75
+ email: string;
76
+ assignedTests: number;
77
+ completedTests: number;
78
+ }
79
+
80
+ interface TestAssignment {
81
+ id: string;
82
+ status: string;
83
+ testCase: {
84
+ id: string;
85
+ title: string;
86
+ description: string;
87
+ steps: TestStep[];
88
+ expectedResult: string;
89
+ priority: string;
90
+ };
91
+ }
92
+ ```
93
+
94
+ ## For Framework Authors
95
+
96
+ If you're building a BugBear integration for a different framework (Vue, Svelte, etc.), use this package as the foundation:
97
+
98
+ ```typescript
99
+ import { BugBearClient, createBugBear, BugBearConfig } from '@bugbearai/core';
100
+
101
+ // Create your framework-specific wrapper around the client
102
+ ```
@@ -0,0 +1,434 @@
1
+ /**
2
+ * BugBear Core Types
3
+ */
4
+ type ReportType = 'bug' | 'feedback' | 'suggestion' | 'test_pass' | 'test_fail';
5
+ type Severity = 'critical' | 'high' | 'medium' | 'low';
6
+ type ReportStatus = 'new' | 'triaging' | 'confirmed' | 'in_progress' | 'fixed' | 'verified' | 'wont_fix' | 'duplicate';
7
+ interface AppContext {
8
+ /** Current route/screen path */
9
+ currentRoute: string;
10
+ /** Current screen name (human readable) */
11
+ screenName?: string;
12
+ /** Property ID if applicable */
13
+ propertyId?: string;
14
+ /** Property name if applicable */
15
+ propertyName?: string;
16
+ /** User's role in current context */
17
+ userRole?: string;
18
+ /** Any additional context the app wants to include */
19
+ custom?: Record<string, unknown>;
20
+ /** Component stack trace (for React errors) */
21
+ componentStack?: string;
22
+ /** Error message if an error occurred */
23
+ errorMessage?: string;
24
+ /** Error stack trace */
25
+ errorStack?: string;
26
+ }
27
+ /** Captured console log entry */
28
+ interface ConsoleLogEntry {
29
+ level: 'log' | 'warn' | 'error' | 'info' | 'debug';
30
+ message: string;
31
+ timestamp: string;
32
+ args?: string[];
33
+ }
34
+ /** Captured network request */
35
+ interface NetworkRequest {
36
+ method: string;
37
+ url: string;
38
+ status?: number;
39
+ duration?: number;
40
+ timestamp: string;
41
+ error?: string;
42
+ }
43
+ /** Enhanced bug context for detailed debugging */
44
+ interface EnhancedBugContext {
45
+ /** Recent console logs (last 50) */
46
+ consoleLogs?: ConsoleLogEntry[];
47
+ /** Recent network requests (last 20) */
48
+ networkRequests?: NetworkRequest[];
49
+ /** Current Redux/state snapshot (serialized) */
50
+ stateSnapshot?: Record<string, unknown>;
51
+ /** Performance metrics */
52
+ performanceMetrics?: {
53
+ pageLoadTime?: number;
54
+ memoryUsage?: number;
55
+ fps?: number;
56
+ };
57
+ /** Browser/environment info */
58
+ environment?: {
59
+ language?: string;
60
+ timezone?: string;
61
+ cookiesEnabled?: boolean;
62
+ localStorage?: boolean;
63
+ online?: boolean;
64
+ };
65
+ }
66
+ interface DeviceInfo {
67
+ /** Platform: ios, android, web */
68
+ platform: 'ios' | 'android' | 'web';
69
+ /** OS version */
70
+ osVersion?: string;
71
+ /** App version */
72
+ appVersion?: string;
73
+ /** Device model */
74
+ deviceModel?: string;
75
+ /** Screen dimensions */
76
+ screenSize?: {
77
+ width: number;
78
+ height: number;
79
+ };
80
+ /** User agent (web) */
81
+ userAgent?: string;
82
+ }
83
+ interface BugBearReport {
84
+ /** Report type */
85
+ type: ReportType;
86
+ /** Description of the issue/feedback */
87
+ description: string;
88
+ /** Short title (can be auto-generated) */
89
+ title?: string;
90
+ /** Severity (for bugs) */
91
+ severity?: Severity;
92
+ /** Which step failed (for test failures) */
93
+ failedAtStep?: string;
94
+ /** Voice audio URL if voice input was used */
95
+ voiceAudioUrl?: string;
96
+ /** Transcribed voice text */
97
+ voiceTranscript?: string;
98
+ /** Screenshot URLs */
99
+ screenshots?: string[];
100
+ /** App context at time of report */
101
+ appContext: AppContext;
102
+ /** Device information */
103
+ deviceInfo: DeviceInfo;
104
+ /** Navigation history (last N screens) */
105
+ navigationHistory?: string[];
106
+ /** Linked test assignment ID (if testing assigned test) */
107
+ assignmentId?: string;
108
+ /** Linked test case ID */
109
+ testCaseId?: string;
110
+ /** Enhanced debugging context */
111
+ enhancedContext?: EnhancedBugContext;
112
+ }
113
+ /** User info from the host application */
114
+ interface HostUserInfo {
115
+ /** User ID from the host app's auth system */
116
+ id: string;
117
+ /** User's email address */
118
+ email: string;
119
+ }
120
+ interface BugBearConfig {
121
+ /** Your BugBear project ID */
122
+ projectId: string;
123
+ /** Supabase URL (uses BugBear's hosted if not provided) */
124
+ supabaseUrl?: string;
125
+ /** Supabase anon key */
126
+ supabaseAnonKey?: string;
127
+ /** Enable voice input */
128
+ enableVoice?: boolean;
129
+ /** Enable screenshot capture */
130
+ enableScreenshots?: boolean;
131
+ /** Custom theme */
132
+ theme?: BugBearTheme;
133
+ /** Callback when report is submitted */
134
+ onReportSubmitted?: (report: BugBearReport) => void;
135
+ /** Function to get current app context */
136
+ getAppContext?: () => AppContext;
137
+ /** Function to get navigation history */
138
+ getNavigationHistory?: () => string[];
139
+ /**
140
+ * Function to get the current user from the host app's auth system.
141
+ * This is required when the host app uses a different Supabase instance.
142
+ * Returns null if no user is logged in.
143
+ */
144
+ getCurrentUser?: () => Promise<HostUserInfo | null>;
145
+ /**
146
+ * Callback to navigate to a specific route/screen.
147
+ * Used for deep linking from test cases to the screen being tested.
148
+ * @param route - The route path (web) or screen name (React Native)
149
+ */
150
+ onNavigate?: (route: string) => void;
151
+ }
152
+ interface BugBearTheme {
153
+ /** Primary brand color */
154
+ primaryColor?: string;
155
+ /** Background color for the widget */
156
+ backgroundColor?: string;
157
+ /** Text color */
158
+ textColor?: string;
159
+ /** Border radius */
160
+ borderRadius?: number;
161
+ }
162
+ type TestTemplate = 'steps' | 'checklist' | 'rubric' | 'freeform';
163
+ type RubricMode = 'pass_fail' | 'rating';
164
+ interface QATrack {
165
+ id: string;
166
+ name: string;
167
+ icon: string;
168
+ color: string;
169
+ testTemplate: TestTemplate;
170
+ /** For rubric/checklist: pass_fail shows checkboxes, rating shows 1-5 scale */
171
+ rubricMode?: RubricMode;
172
+ description?: string;
173
+ }
174
+ interface TestAssignment {
175
+ id: string;
176
+ testCase: {
177
+ id: string;
178
+ title: string;
179
+ testKey: string;
180
+ description?: string;
181
+ steps: TestStep[];
182
+ expectedResult: string;
183
+ priority: string;
184
+ /** Route/screen to navigate to when starting this test */
185
+ targetRoute?: string;
186
+ track?: QATrack;
187
+ };
188
+ status: 'pending' | 'in_progress' | 'passed' | 'failed' | 'blocked';
189
+ }
190
+ interface TestStep {
191
+ stepNumber: number;
192
+ action: string;
193
+ expectedResult?: string;
194
+ }
195
+ /** Result data for different template types */
196
+ interface ChecklistResult {
197
+ itemIndex: number;
198
+ passed: boolean;
199
+ note?: string;
200
+ }
201
+ interface RubricResult {
202
+ criterionIndex: number;
203
+ rating: 1 | 2 | 3 | 4 | 5;
204
+ note?: string;
205
+ }
206
+ interface TestResult {
207
+ /** For checklist template */
208
+ checklistResults?: ChecklistResult[];
209
+ /** For rubric template */
210
+ rubricResults?: RubricResult[];
211
+ /** For freeform template */
212
+ freeformObservations?: string;
213
+ /** Overall notes */
214
+ notes?: string;
215
+ }
216
+ interface TesterInfo {
217
+ id: string;
218
+ name: string;
219
+ email: string;
220
+ assignedTests: number;
221
+ completedTests: number;
222
+ }
223
+ type ThreadType = 'announcement' | 'direct' | 'report' | 'general_note';
224
+ type ThreadPriority = 'low' | 'normal' | 'high' | 'urgent';
225
+ type MessageSenderType = 'admin' | 'tester';
226
+ interface TesterThread {
227
+ id: string;
228
+ subject: string | null;
229
+ threadType: ThreadType;
230
+ priority: ThreadPriority;
231
+ isPinned: boolean;
232
+ isResolved: boolean;
233
+ lastMessageAt: string;
234
+ createdAt: string;
235
+ unreadCount: number;
236
+ lastMessage?: TesterMessage;
237
+ }
238
+ interface TesterMessage {
239
+ id: string;
240
+ threadId: string;
241
+ senderType: MessageSenderType;
242
+ senderName: string;
243
+ content: string;
244
+ createdAt: string;
245
+ attachments: Array<{
246
+ type: 'image' | 'document' | 'video_link';
247
+ url: string;
248
+ name: string;
249
+ }>;
250
+ }
251
+
252
+ /**
253
+ * BugBear Client
254
+ * Handles communication with the BugBear backend
255
+ */
256
+
257
+ declare class BugBearClient {
258
+ private supabase;
259
+ private config;
260
+ private navigationHistory;
261
+ constructor(config: BugBearConfig);
262
+ /**
263
+ * Track navigation for context
264
+ */
265
+ trackNavigation(route: string): void;
266
+ /**
267
+ * Get current navigation history
268
+ */
269
+ getNavigationHistory(): string[];
270
+ /**
271
+ * Get current user info from host app or BugBear's own auth
272
+ */
273
+ private getCurrentUserInfo;
274
+ /**
275
+ * Submit a report
276
+ */
277
+ submitReport(report: Omit<BugBearReport, 'deviceInfo' | 'navigationHistory'> & {
278
+ deviceInfo?: DeviceInfo;
279
+ }): Promise<{
280
+ success: boolean;
281
+ reportId?: string;
282
+ error?: string;
283
+ }>;
284
+ /**
285
+ * Get assigned tests for current user
286
+ * First looks up the tester by email, then fetches their assignments
287
+ */
288
+ getAssignedTests(): Promise<TestAssignment[]>;
289
+ /**
290
+ * Get current tester info
291
+ * Looks up tester by email from the host app's authenticated user
292
+ */
293
+ getTesterInfo(): Promise<TesterInfo | null>;
294
+ /**
295
+ * Check if current user is a tester for this project
296
+ */
297
+ isTester(): Promise<boolean>;
298
+ /**
299
+ * Check if QA mode is enabled for this project
300
+ * This is a master switch that admins can toggle in the dashboard
301
+ */
302
+ isQAEnabled(): Promise<boolean>;
303
+ /**
304
+ * Check if the widget should be visible
305
+ * (QA mode enabled AND current user is a tester)
306
+ */
307
+ shouldShowWidget(): Promise<boolean>;
308
+ /**
309
+ * Upload a screenshot
310
+ */
311
+ uploadScreenshot(file: File | Blob, filename?: string): Promise<string | null>;
312
+ /**
313
+ * Generate a title from the report content
314
+ */
315
+ private generateTitle;
316
+ /**
317
+ * Get device info (override in platform-specific implementations)
318
+ */
319
+ private getDeviceInfo;
320
+ /**
321
+ * Create a fix request for Claude Code to pick up
322
+ * Called from the dashboard when user clicks "Send to Claude Code"
323
+ */
324
+ createFixRequest(request: {
325
+ title: string;
326
+ description?: string;
327
+ prompt: string;
328
+ filePath?: string;
329
+ reportId?: string;
330
+ }): Promise<{
331
+ success: boolean;
332
+ fixRequestId?: string;
333
+ error?: string;
334
+ }>;
335
+ /**
336
+ * Get pending fix requests for this project
337
+ * Useful for dashboard to show queue status
338
+ */
339
+ getFixRequests(options?: {
340
+ status?: 'pending' | 'claimed' | 'completed' | 'cancelled';
341
+ limit?: number;
342
+ }): Promise<Array<{
343
+ id: string;
344
+ title: string;
345
+ description: string | null;
346
+ status: string;
347
+ claimedBy: string | null;
348
+ claimedAt: string | null;
349
+ completedAt: string | null;
350
+ createdAt: string;
351
+ }>>;
352
+ /**
353
+ * Get threads visible to the current tester
354
+ * Includes threads where audience is 'all' or tester is in audience_tester_ids
355
+ */
356
+ getThreadsForTester(): Promise<TesterThread[]>;
357
+ /**
358
+ * Get all messages in a thread
359
+ */
360
+ getThreadMessages(threadId: string): Promise<TesterMessage[]>;
361
+ /**
362
+ * Send a message to a thread
363
+ */
364
+ sendMessage(threadId: string, content: string): Promise<boolean>;
365
+ /**
366
+ * Mark a thread as read
367
+ */
368
+ markThreadAsRead(threadId: string): Promise<void>;
369
+ /**
370
+ * Get total unread message count across all threads
371
+ */
372
+ getUnreadCount(): Promise<number>;
373
+ }
374
+ /**
375
+ * Create a BugBear client instance
376
+ */
377
+ declare function createBugBear(config: BugBearConfig): BugBearClient;
378
+
379
+ /**
380
+ * BugBear Context Capture
381
+ * Utilities for capturing enhanced debugging context
382
+ */
383
+
384
+ /**
385
+ * Context capture singleton that captures console logs and network requests
386
+ */
387
+ declare class ContextCaptureManager {
388
+ private consoleLogs;
389
+ private networkRequests;
390
+ private originalConsole;
391
+ private originalFetch?;
392
+ private isCapturing;
393
+ /**
394
+ * Start capturing console logs and network requests
395
+ */
396
+ startCapture(): void;
397
+ /**
398
+ * Stop capturing and restore original functions
399
+ */
400
+ stopCapture(): void;
401
+ /**
402
+ * Get captured context for a bug report
403
+ */
404
+ getEnhancedContext(): EnhancedBugContext;
405
+ /**
406
+ * Clear captured data
407
+ */
408
+ clear(): void;
409
+ /**
410
+ * Add a log entry manually (for custom logging)
411
+ */
412
+ addLog(level: ConsoleLogEntry['level'], message: string, args?: string[]): void;
413
+ /**
414
+ * Add a network request manually
415
+ */
416
+ addNetworkRequest(request: NetworkRequest): void;
417
+ private captureConsole;
418
+ private captureFetch;
419
+ private getPerformanceMetrics;
420
+ private getEnvironmentInfo;
421
+ }
422
+ declare const contextCapture: ContextCaptureManager;
423
+ /**
424
+ * Create an error boundary handler that captures React errors
425
+ */
426
+ declare function captureError(error: Error, errorInfo?: {
427
+ componentStack?: string;
428
+ }): {
429
+ errorMessage: string;
430
+ errorStack?: string;
431
+ componentStack?: string;
432
+ };
433
+
434
+ export { type AppContext, BugBearClient, type BugBearConfig, type BugBearReport, type BugBearTheme, type ChecklistResult, type ConsoleLogEntry, type DeviceInfo, type EnhancedBugContext, type HostUserInfo, type MessageSenderType, type NetworkRequest, type QATrack, type ReportStatus, type ReportType, type RubricMode, type RubricResult, type Severity, type TestAssignment, type TestResult, type TestStep, type TestTemplate, type TesterInfo, type TesterMessage, type TesterThread, type ThreadPriority, type ThreadType, captureError, contextCapture, createBugBear };