@bbearai/core 0.9.13 → 0.10.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.mts CHANGED
@@ -497,6 +497,8 @@ interface TesterInfo {
497
497
  completedTests: number;
498
498
  /** Role: 'tester' for QA testers, 'feedback' for feedback-only users */
499
499
  role?: 'tester' | 'feedback';
500
+ /** When set and in the future, the widget should be hidden for this tester */
501
+ widgetPausedUntil?: string;
500
502
  }
501
503
  interface TesterProfileUpdate {
502
504
  name?: string;
@@ -828,14 +830,12 @@ interface QATask {
828
830
  updatedAt: string;
829
831
  }
830
832
  /** Category for filtering tester issues in the widget */
831
- type IssueCategory = 'open' | 'retest' | 'done' | 'wont_fix' | 'reopened';
833
+ type IssueCategory = 'open' | 'fixed' | 'closed';
832
834
  /** Issue counts for each category (HomeScreen cards) */
833
835
  interface IssueCounts {
834
836
  open: number;
835
- retest: number;
836
- done: number;
837
- wont_fix: number;
838
- reopened: number;
837
+ fixed: number;
838
+ closed: number;
839
839
  }
840
840
  /** A report as seen by the tester in the widget */
841
841
  interface TesterIssue {
@@ -1259,6 +1259,7 @@ declare class BugBearClient {
1259
1259
  onAssignmentChange?: () => void;
1260
1260
  onMessageChange?: () => void;
1261
1261
  onReportChange?: () => void;
1262
+ onTesterChange?: () => void;
1262
1263
  }): () => void;
1263
1264
  /** Remove all active Realtime channels. */
1264
1265
  unsubscribeAll(): void;
@@ -1444,6 +1445,14 @@ declare class BugBearClient {
1444
1445
  success: boolean;
1445
1446
  error?: string;
1446
1447
  }>;
1448
+ /**
1449
+ * Verify a fixed issue — tester confirms the fix works.
1450
+ * Transitions the report from fixed/ready_to_test to 'verified'.
1451
+ */
1452
+ verifyReport(reportId: string): Promise<{
1453
+ success: boolean;
1454
+ error?: string;
1455
+ }>;
1447
1456
  /**
1448
1457
  * Basic email format validation (defense in depth)
1449
1458
  */
package/dist/index.d.ts CHANGED
@@ -497,6 +497,8 @@ interface TesterInfo {
497
497
  completedTests: number;
498
498
  /** Role: 'tester' for QA testers, 'feedback' for feedback-only users */
499
499
  role?: 'tester' | 'feedback';
500
+ /** When set and in the future, the widget should be hidden for this tester */
501
+ widgetPausedUntil?: string;
500
502
  }
501
503
  interface TesterProfileUpdate {
502
504
  name?: string;
@@ -828,14 +830,12 @@ interface QATask {
828
830
  updatedAt: string;
829
831
  }
830
832
  /** Category for filtering tester issues in the widget */
831
- type IssueCategory = 'open' | 'retest' | 'done' | 'wont_fix' | 'reopened';
833
+ type IssueCategory = 'open' | 'fixed' | 'closed';
832
834
  /** Issue counts for each category (HomeScreen cards) */
833
835
  interface IssueCounts {
834
836
  open: number;
835
- retest: number;
836
- done: number;
837
- wont_fix: number;
838
- reopened: number;
837
+ fixed: number;
838
+ closed: number;
839
839
  }
840
840
  /** A report as seen by the tester in the widget */
841
841
  interface TesterIssue {
@@ -1259,6 +1259,7 @@ declare class BugBearClient {
1259
1259
  onAssignmentChange?: () => void;
1260
1260
  onMessageChange?: () => void;
1261
1261
  onReportChange?: () => void;
1262
+ onTesterChange?: () => void;
1262
1263
  }): () => void;
1263
1264
  /** Remove all active Realtime channels. */
1264
1265
  unsubscribeAll(): void;
@@ -1444,6 +1445,14 @@ declare class BugBearClient {
1444
1445
  success: boolean;
1445
1446
  error?: string;
1446
1447
  }>;
1448
+ /**
1449
+ * Verify a fixed issue — tester confirms the fix works.
1450
+ * Transitions the report from fixed/ready_to_test to 'verified'.
1451
+ */
1452
+ verifyReport(reportId: string): Promise<{
1453
+ success: boolean;
1454
+ error?: string;
1455
+ }>;
1447
1456
  /**
1448
1457
  * Basic email format validation (defense in depth)
1449
1458
  */
package/dist/index.js CHANGED
@@ -1279,6 +1279,20 @@ var BugBearClient = class {
1279
1279
  });
1280
1280
  this.realtimeChannels.push(channel);
1281
1281
  }
1282
+ if (callbacks.onTesterChange) {
1283
+ const debouncedCb = debounce(callbacks.onTesterChange);
1284
+ const channel = this.supabase.channel("bugbear-testers").on("postgres_changes", {
1285
+ event: "UPDATE",
1286
+ schema: "public",
1287
+ table: "testers",
1288
+ filter: `project_id=eq.${projectId}`
1289
+ }, debouncedCb).subscribe((status) => {
1290
+ if (status === "CHANNEL_ERROR") {
1291
+ console.warn("BugBear: Realtime subscription failed for testers");
1292
+ }
1293
+ });
1294
+ this.realtimeChannels.push(channel);
1295
+ }
1282
1296
  return () => this.unsubscribeAll();
1283
1297
  }
1284
1298
  /** Remove all active Realtime channels. */
@@ -2164,7 +2178,8 @@ var BugBearClient = class {
2164
2178
  platforms: tester.platforms || [],
2165
2179
  assignedTests: tester.assigned_count || 0,
2166
2180
  completedTests: tester.completed_count || 0,
2167
- role: tester.role || "tester"
2181
+ role: tester.role || "tester",
2182
+ widgetPausedUntil: tester.widget_paused_until || void 0
2168
2183
  };
2169
2184
  } catch (err) {
2170
2185
  console.error("BugBear: getTesterInfo error", err);
@@ -2199,7 +2214,7 @@ var BugBearClient = class {
2199
2214
  * @param mineOnly - If true (default), only counts the tester's own reports. If false, counts all project reports.
2200
2215
  */
2201
2216
  async getIssueCounts(mineOnly = true) {
2202
- const empty = { open: 0, retest: 0, done: 0, wont_fix: 0, reopened: 0 };
2217
+ const empty = { open: 0, fixed: 0, closed: 0 };
2203
2218
  try {
2204
2219
  const testerInfo = await this.getTesterInfo();
2205
2220
  if (!testerInfo) return empty;
@@ -2214,10 +2229,8 @@ var BugBearClient = class {
2214
2229
  }
2215
2230
  return {
2216
2231
  open: data?.open ?? 0,
2217
- retest: data?.retest ?? 0,
2218
- done: data?.done ?? 0,
2219
- wont_fix: data?.wont_fix ?? 0,
2220
- reopened: data?.reopened ?? 0
2232
+ fixed: data?.fixed ?? 0,
2233
+ closed: data?.closed ?? 0
2221
2234
  };
2222
2235
  } catch (err) {
2223
2236
  console.error("BugBear: Error fetching issue counts", err);
@@ -2297,6 +2310,31 @@ var BugBearClient = class {
2297
2310
  return { success: false, error: "Unexpected error" };
2298
2311
  }
2299
2312
  }
2313
+ /**
2314
+ * Verify a fixed issue — tester confirms the fix works.
2315
+ * Transitions the report from fixed/ready_to_test to 'verified'.
2316
+ */
2317
+ async verifyReport(reportId) {
2318
+ try {
2319
+ const testerInfo = await this.getTesterInfo();
2320
+ if (!testerInfo) return { success: false, error: "Not authenticated as tester" };
2321
+ const { data, error } = await this.supabase.rpc("verify_report", {
2322
+ p_report_id: reportId,
2323
+ p_tester_id: testerInfo.id
2324
+ });
2325
+ if (error) {
2326
+ console.error("BugBear: Failed to verify report", formatPgError(error));
2327
+ return { success: false, error: error.message };
2328
+ }
2329
+ if (!data?.success) {
2330
+ return { success: false, error: data?.error || "Failed to verify report" };
2331
+ }
2332
+ return { success: true };
2333
+ } catch (err) {
2334
+ console.error("BugBear: Error verifying report", err);
2335
+ return { success: false, error: "Unexpected error" };
2336
+ }
2337
+ }
2300
2338
  /**
2301
2339
  * Basic email format validation (defense in depth)
2302
2340
  */
package/dist/index.mjs CHANGED
@@ -1233,6 +1233,20 @@ var BugBearClient = class {
1233
1233
  });
1234
1234
  this.realtimeChannels.push(channel);
1235
1235
  }
1236
+ if (callbacks.onTesterChange) {
1237
+ const debouncedCb = debounce(callbacks.onTesterChange);
1238
+ const channel = this.supabase.channel("bugbear-testers").on("postgres_changes", {
1239
+ event: "UPDATE",
1240
+ schema: "public",
1241
+ table: "testers",
1242
+ filter: `project_id=eq.${projectId}`
1243
+ }, debouncedCb).subscribe((status) => {
1244
+ if (status === "CHANNEL_ERROR") {
1245
+ console.warn("BugBear: Realtime subscription failed for testers");
1246
+ }
1247
+ });
1248
+ this.realtimeChannels.push(channel);
1249
+ }
1236
1250
  return () => this.unsubscribeAll();
1237
1251
  }
1238
1252
  /** Remove all active Realtime channels. */
@@ -2118,7 +2132,8 @@ var BugBearClient = class {
2118
2132
  platforms: tester.platforms || [],
2119
2133
  assignedTests: tester.assigned_count || 0,
2120
2134
  completedTests: tester.completed_count || 0,
2121
- role: tester.role || "tester"
2135
+ role: tester.role || "tester",
2136
+ widgetPausedUntil: tester.widget_paused_until || void 0
2122
2137
  };
2123
2138
  } catch (err) {
2124
2139
  console.error("BugBear: getTesterInfo error", err);
@@ -2153,7 +2168,7 @@ var BugBearClient = class {
2153
2168
  * @param mineOnly - If true (default), only counts the tester's own reports. If false, counts all project reports.
2154
2169
  */
2155
2170
  async getIssueCounts(mineOnly = true) {
2156
- const empty = { open: 0, retest: 0, done: 0, wont_fix: 0, reopened: 0 };
2171
+ const empty = { open: 0, fixed: 0, closed: 0 };
2157
2172
  try {
2158
2173
  const testerInfo = await this.getTesterInfo();
2159
2174
  if (!testerInfo) return empty;
@@ -2168,10 +2183,8 @@ var BugBearClient = class {
2168
2183
  }
2169
2184
  return {
2170
2185
  open: data?.open ?? 0,
2171
- retest: data?.retest ?? 0,
2172
- done: data?.done ?? 0,
2173
- wont_fix: data?.wont_fix ?? 0,
2174
- reopened: data?.reopened ?? 0
2186
+ fixed: data?.fixed ?? 0,
2187
+ closed: data?.closed ?? 0
2175
2188
  };
2176
2189
  } catch (err) {
2177
2190
  console.error("BugBear: Error fetching issue counts", err);
@@ -2251,6 +2264,31 @@ var BugBearClient = class {
2251
2264
  return { success: false, error: "Unexpected error" };
2252
2265
  }
2253
2266
  }
2267
+ /**
2268
+ * Verify a fixed issue — tester confirms the fix works.
2269
+ * Transitions the report from fixed/ready_to_test to 'verified'.
2270
+ */
2271
+ async verifyReport(reportId) {
2272
+ try {
2273
+ const testerInfo = await this.getTesterInfo();
2274
+ if (!testerInfo) return { success: false, error: "Not authenticated as tester" };
2275
+ const { data, error } = await this.supabase.rpc("verify_report", {
2276
+ p_report_id: reportId,
2277
+ p_tester_id: testerInfo.id
2278
+ });
2279
+ if (error) {
2280
+ console.error("BugBear: Failed to verify report", formatPgError(error));
2281
+ return { success: false, error: error.message };
2282
+ }
2283
+ if (!data?.success) {
2284
+ return { success: false, error: data?.error || "Failed to verify report" };
2285
+ }
2286
+ return { success: true };
2287
+ } catch (err) {
2288
+ console.error("BugBear: Error verifying report", err);
2289
+ return { success: false, error: "Unexpected error" };
2290
+ }
2291
+ }
2254
2292
  /**
2255
2293
  * Basic email format validation (defense in depth)
2256
2294
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bbearai/core",
3
- "version": "0.9.13",
3
+ "version": "0.10.0",
4
4
  "description": "Core utilities and types for BugBear QA platform",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",