@bbearai/core 0.2.12 → 0.2.13

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
@@ -2,7 +2,7 @@
2
2
 
3
3
  Core client and utilities for BugBear QA platform.
4
4
 
5
- > **Note:** Most users should install `@bbearai/react` instead, which includes this package automatically.
5
+ > **Note:** Most users should install `@bbearai/react` or `@bbearai/react-native` instead, which include this package automatically.
6
6
 
7
7
  ## Installation
8
8
 
@@ -20,6 +20,7 @@ const bugbear = createBugBear({
20
20
  getCurrentUser: async () => ({
21
21
  id: 'user-123',
22
22
  email: 'user@example.com',
23
+ name: 'Jane Doe', // Optional, used for reporter identity
23
24
  }),
24
25
  });
25
26
 
@@ -28,6 +29,7 @@ await bugbear.submitReport({
28
29
  type: 'bug',
29
30
  description: 'Button does not work',
30
31
  severity: 'high',
32
+ appContext: { currentRoute: '/dashboard' },
31
33
  });
32
34
 
33
35
  // Check if user is a tester
@@ -37,13 +39,84 @@ const isTester = await bugbear.isTester();
37
39
  const assignments = await bugbear.getAssignedTests();
38
40
  ```
39
41
 
40
- ## API Reference
42
+ ## Configuration
41
43
 
42
- ### createBugBear(config)
44
+ ```typescript
45
+ interface BugBearConfig {
46
+ // Required
47
+ projectId: string;
48
+ getCurrentUser: () => Promise<{ id: string; email: string; name?: string } | null>;
49
+
50
+ // Optional — context
51
+ getAppContext?: () => AppContext; // Rich app context (userRole, etc.)
52
+ getNavigationHistory?: () => string[]; // Custom navigation tracking
53
+
54
+ // Optional — callbacks
55
+ onReportSubmitted?: (report: BugBearReport) => void;
56
+ onNavigate?: (route: string) => void; // Deep linking from test cases
57
+
58
+ // Optional — self-hosted
59
+ supabaseUrl?: string;
60
+ supabaseAnonKey?: string;
61
+ }
62
+ ```
63
+
64
+ ### AppContext
65
+
66
+ Provide `getAppContext` to attach rich context to every bug report. This helps the developer fixing the bug understand the user's state:
67
+
68
+ ```typescript
69
+ const bugbear = createBugBear({
70
+ projectId: 'your-project-id',
71
+ getCurrentUser: async () => ({ id: user.id, email: user.email }),
72
+ getAppContext: () => ({
73
+ currentRoute: window.location.pathname,
74
+ userRole: currentUser?.role, // e.g. 'owner', 'manager', 'guest'
75
+ propertyId: currentProperty?.id, // App-specific context
76
+ custom: { // Any additional context
77
+ theme: 'dark',
78
+ locale: 'en-US',
79
+ },
80
+ }),
81
+ });
82
+ ```
83
+
84
+ ## Automatic Context Capture
85
+
86
+ BugBear automatically captures debugging context when initialized via `BugBearProvider` (React or React Native). No manual setup required.
43
87
 
44
- Creates a BugBear client instance.
88
+ **What's captured automatically:**
45
89
 
46
- ### Client Methods
90
+ | Data | Details |
91
+ |------|---------|
92
+ | **Console logs** | Last 50 `console.log/warn/error/info` calls |
93
+ | **Network requests** | Last 20 `fetch()` calls with method, URL, status, duration |
94
+ | **Failed response bodies** | First 500 chars of response body for 4xx/5xx errors |
95
+ | **Navigation history** | Last 20 route changes (via `pushState`/`replaceState`/`popstate`) |
96
+ | **Performance metrics** | Page load time, memory usage (Chrome) |
97
+ | **Environment** | Language, timezone, online status, cookies, localStorage |
98
+
99
+ This data is attached to every bug report as `enhanced_context` and is available to the MCP server's `get_report_context` tool.
100
+
101
+ ### Manual Capture (framework authors)
102
+
103
+ If you're not using `BugBearProvider`, start capture manually:
104
+
105
+ ```typescript
106
+ import { contextCapture } from '@bbearai/core';
107
+
108
+ // Start capturing (call once at app init)
109
+ contextCapture.startCapture();
110
+
111
+ // For React Native: manually track screen changes
112
+ contextCapture.trackNavigation('/home');
113
+ contextCapture.trackNavigation('/settings');
114
+
115
+ // Get captured data (automatically included in submitReport)
116
+ const context = contextCapture.getEnhancedContext();
117
+ ```
118
+
119
+ ## Client Methods
47
120
 
48
121
  | Method | Description |
49
122
  |--------|-------------|
@@ -53,7 +126,9 @@ Creates a BugBear client instance.
53
126
  | `shouldShowWidget()` | Check if widget should be visible (QA enabled + is tester) |
54
127
  | `getTesterInfo()` | Get current tester's info |
55
128
  | `getAssignedTests()` | Get test cases assigned to current tester |
56
- | `trackNavigation(route)` | Track navigation for context |
129
+ | `getAppContext()` | Get current app context (uses config callback or auto-captured) |
130
+ | `getNavigationHistory()` | Get navigation history (config callback > manual > auto-captured) |
131
+ | `trackNavigation(route)` | Manually track a route change |
57
132
  | `uploadScreenshot(file)` | Upload a screenshot |
58
133
 
59
134
  ## Types
@@ -66,7 +141,15 @@ interface BugBearReport {
66
141
  severity?: 'critical' | 'high' | 'medium' | 'low';
67
142
  screenshots?: string[];
68
143
  appContext?: AppContext;
69
- // ... and more
144
+ enhancedContext?: EnhancedBugContext;
145
+ }
146
+
147
+ interface AppContext {
148
+ currentRoute: string;
149
+ screenName?: string;
150
+ userRole?: string;
151
+ propertyId?: string;
152
+ custom?: Record<string, unknown>;
70
153
  }
71
154
 
72
155
  interface TesterInfo {
@@ -96,7 +179,11 @@ interface TestAssignment {
96
179
  If you're building a BugBear integration for a different framework (Vue, Svelte, etc.), use this package as the foundation:
97
180
 
98
181
  ```typescript
99
- import { BugBearClient, createBugBear, BugBearConfig } from '@bbearai/core';
182
+ import { BugBearClient, createBugBear, contextCapture, BugBearConfig } from '@bbearai/core';
183
+
184
+ // Start context capture at app init
185
+ contextCapture.startCapture();
100
186
 
101
187
  // Create your framework-specific wrapper around the client
188
+ const client = createBugBear(config);
102
189
  ```
package/dist/index.d.mts CHANGED
@@ -662,11 +662,30 @@ declare class BugBearClient {
662
662
  error?: string;
663
663
  durationSeconds?: number;
664
664
  }>;
665
+ /**
666
+ * Pass a test assignment — convenience wrapper around updateAssignmentStatus
667
+ */
668
+ passAssignment(assignmentId: string): Promise<{
669
+ success: boolean;
670
+ error?: string;
671
+ durationSeconds?: number;
672
+ }>;
673
+ /**
674
+ * Fail a test assignment — convenience wrapper around updateAssignmentStatus
675
+ */
676
+ failAssignment(assignmentId: string): Promise<{
677
+ success: boolean;
678
+ error?: string;
679
+ durationSeconds?: number;
680
+ }>;
665
681
  /**
666
682
  * Skip a test assignment with a required reason
667
683
  * Marks the assignment as 'skipped' and records why it was skipped
668
684
  */
669
- skipAssignment(assignmentId: string, reason: SkipReason, notes?: string): Promise<{
685
+ skipAssignment(assignmentId: string, reason: SkipReason | {
686
+ reason: SkipReason;
687
+ notes?: string;
688
+ }, notes?: string): Promise<{
670
689
  success: boolean;
671
690
  error?: string;
672
691
  }>;
package/dist/index.d.ts CHANGED
@@ -662,11 +662,30 @@ declare class BugBearClient {
662
662
  error?: string;
663
663
  durationSeconds?: number;
664
664
  }>;
665
+ /**
666
+ * Pass a test assignment — convenience wrapper around updateAssignmentStatus
667
+ */
668
+ passAssignment(assignmentId: string): Promise<{
669
+ success: boolean;
670
+ error?: string;
671
+ durationSeconds?: number;
672
+ }>;
673
+ /**
674
+ * Fail a test assignment — convenience wrapper around updateAssignmentStatus
675
+ */
676
+ failAssignment(assignmentId: string): Promise<{
677
+ success: boolean;
678
+ error?: string;
679
+ durationSeconds?: number;
680
+ }>;
665
681
  /**
666
682
  * Skip a test assignment with a required reason
667
683
  * Marks the assignment as 'skipped' and records why it was skipped
668
684
  */
669
- skipAssignment(assignmentId: string, reason: SkipReason, notes?: string): Promise<{
685
+ skipAssignment(assignmentId: string, reason: SkipReason | {
686
+ reason: SkipReason;
687
+ notes?: string;
688
+ }, notes?: string): Promise<{
670
689
  success: boolean;
671
690
  error?: string;
672
691
  }>;
package/dist/index.js CHANGED
@@ -630,19 +630,40 @@ var BugBearClient = class {
630
630
  return { success: false, error: message };
631
631
  }
632
632
  }
633
+ /**
634
+ * Pass a test assignment — convenience wrapper around updateAssignmentStatus
635
+ */
636
+ async passAssignment(assignmentId) {
637
+ return this.updateAssignmentStatus(assignmentId, "passed");
638
+ }
639
+ /**
640
+ * Fail a test assignment — convenience wrapper around updateAssignmentStatus
641
+ */
642
+ async failAssignment(assignmentId) {
643
+ return this.updateAssignmentStatus(assignmentId, "failed");
644
+ }
633
645
  /**
634
646
  * Skip a test assignment with a required reason
635
647
  * Marks the assignment as 'skipped' and records why it was skipped
636
648
  */
637
649
  async skipAssignment(assignmentId, reason, notes) {
650
+ let actualReason;
651
+ let actualNotes;
652
+ if (typeof reason === "object") {
653
+ actualReason = reason.reason;
654
+ actualNotes = reason.notes;
655
+ } else {
656
+ actualReason = reason;
657
+ actualNotes = notes;
658
+ }
638
659
  try {
639
660
  const updateData = {
640
661
  status: "skipped",
641
- skip_reason: reason,
662
+ skip_reason: actualReason,
642
663
  completed_at: (/* @__PURE__ */ new Date()).toISOString()
643
664
  };
644
- if (notes) {
645
- updateData.notes = notes;
665
+ if (actualNotes) {
666
+ updateData.notes = actualNotes;
646
667
  }
647
668
  const { error } = await this.supabase.from("test_assignments").update(updateData).eq("id", assignmentId);
648
669
  if (error) {
package/dist/index.mjs CHANGED
@@ -601,19 +601,40 @@ var BugBearClient = class {
601
601
  return { success: false, error: message };
602
602
  }
603
603
  }
604
+ /**
605
+ * Pass a test assignment — convenience wrapper around updateAssignmentStatus
606
+ */
607
+ async passAssignment(assignmentId) {
608
+ return this.updateAssignmentStatus(assignmentId, "passed");
609
+ }
610
+ /**
611
+ * Fail a test assignment — convenience wrapper around updateAssignmentStatus
612
+ */
613
+ async failAssignment(assignmentId) {
614
+ return this.updateAssignmentStatus(assignmentId, "failed");
615
+ }
604
616
  /**
605
617
  * Skip a test assignment with a required reason
606
618
  * Marks the assignment as 'skipped' and records why it was skipped
607
619
  */
608
620
  async skipAssignment(assignmentId, reason, notes) {
621
+ let actualReason;
622
+ let actualNotes;
623
+ if (typeof reason === "object") {
624
+ actualReason = reason.reason;
625
+ actualNotes = reason.notes;
626
+ } else {
627
+ actualReason = reason;
628
+ actualNotes = notes;
629
+ }
609
630
  try {
610
631
  const updateData = {
611
632
  status: "skipped",
612
- skip_reason: reason,
633
+ skip_reason: actualReason,
613
634
  completed_at: (/* @__PURE__ */ new Date()).toISOString()
614
635
  };
615
- if (notes) {
616
- updateData.notes = notes;
636
+ if (actualNotes) {
637
+ updateData.notes = actualNotes;
617
638
  }
618
639
  const { error } = await this.supabase.from("test_assignments").update(updateData).eq("id", assignmentId);
619
640
  if (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bbearai/core",
3
- "version": "0.2.12",
3
+ "version": "0.2.13",
4
4
  "description": "Core utilities and types for BugBear QA platform",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",