@bbearai/react-native 0.10.1 → 0.10.3

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
@@ -84,6 +84,8 @@ interface BugBearContextValue {
84
84
  success: boolean;
85
85
  error?: string;
86
86
  }>;
87
+ /** Track a navigation event (call from React Navigation's onStateChange) */
88
+ trackNavigation: (routeName: string) => void;
87
89
  /** Number of queued offline operations waiting to be sent. */
88
90
  queuedCount: number;
89
91
  /** URL to the BugBear web dashboard (for linking testers to the full web experience) */
package/dist/index.d.ts CHANGED
@@ -84,6 +84,8 @@ interface BugBearContextValue {
84
84
  success: boolean;
85
85
  error?: string;
86
86
  }>;
87
+ /** Track a navigation event (call from React Navigation's onStateChange) */
88
+ trackNavigation: (routeName: string) => void;
87
89
  /** Number of queued offline operations waiting to be sent. */
88
90
  queuedCount: number;
89
91
  /** URL to the BugBear web dashboard (for linking testers to the full web experience) */
package/dist/index.js CHANGED
@@ -12838,7 +12838,7 @@ var BugBearClient = class {
12838
12838
  } : {
12839
12839
  // Standalone verification assignment (bug reported without a test case)
12840
12840
  id: item.original_report_id || item.id,
12841
- title: item.notes || "Bug Verification",
12841
+ title: item.notes?.replace(/^Verification:\s*/i, "") || "Bug Verification",
12842
12842
  testKey: "VERIFY",
12843
12843
  description: "Verify that the reported bug has been fixed",
12844
12844
  steps: [],
@@ -14826,6 +14826,8 @@ var BugBearContext = (0, import_react.createContext)({
14826
14826
  refreshIssueCounts: async () => {
14827
14827
  },
14828
14828
  reopenReport: async () => ({ success: false }),
14829
+ trackNavigation: () => {
14830
+ },
14829
14831
  queuedCount: 0,
14830
14832
  dashboardUrl: void 0,
14831
14833
  onError: void 0
@@ -14940,8 +14942,11 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
14940
14942
  const enhanced = contextCapture.getEnhancedContext();
14941
14943
  const enriched = {
14942
14944
  ...options,
14945
+ route: options.route ?? contextCapture.getCurrentRoute?.(),
14943
14946
  consoleLogs: options.consoleLogs ?? enhanced.consoleLogs,
14944
- networkSnapshot: options.networkSnapshot ?? enhanced.networkRequests
14947
+ networkSnapshot: options.networkSnapshot ?? enhanced.networkRequests,
14948
+ appContext: options.appContext ?? client.getAppContext(),
14949
+ deviceInfo: options.deviceInfo ?? getDeviceInfo()
14945
14950
  };
14946
14951
  const result = await client.addFinding(activeSession.id, enriched);
14947
14952
  if (result.success && result.finding) {
@@ -14949,7 +14954,10 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
14949
14954
  setActiveSession((prev) => prev ? { ...prev, findingsCount: prev.findingsCount + 1 } : null);
14950
14955
  }
14951
14956
  return result;
14952
- }, [client, activeSession]);
14957
+ }, [client, activeSession, getDeviceInfo]);
14958
+ const trackNavigation = (0, import_react.useCallback)((routeName) => {
14959
+ if (client) client.trackNavigation(routeName);
14960
+ }, [client]);
14953
14961
  const updateTesterProfile = (0, import_react.useCallback)(async (updates) => {
14954
14962
  if (!client) return { success: false, error: "Client not initialized" };
14955
14963
  const result = await client.updateTesterProfile(updates);
@@ -15227,6 +15235,7 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
15227
15235
  issueCounts,
15228
15236
  refreshIssueCounts,
15229
15237
  reopenReport,
15238
+ trackNavigation,
15230
15239
  queuedCount,
15231
15240
  dashboardUrl: config.dashboardUrl,
15232
15241
  onError: config.onError
@@ -15559,27 +15568,27 @@ function HomeScreen({ nav }) {
15559
15568
  /* @__PURE__ */ import_react4.default.createElement(import_react_native4.View, { style: styles7.sessionDot }),
15560
15569
  /* @__PURE__ */ import_react4.default.createElement(import_react_native4.View, { style: styles7.sessionCardContent }, /* @__PURE__ */ import_react4.default.createElement(import_react_native4.Text, { style: styles7.sessionCardTitle, numberOfLines: 1 }, activeSession.focusArea || "QA Session"), /* @__PURE__ */ import_react4.default.createElement(import_react_native4.Text, { style: styles7.sessionCardMeta }, formatTimer(sessionElapsed), " \xB7 ", sessionFindings.length, " finding", sessionFindings.length !== 1 ? "s" : "")),
15561
15570
  /* @__PURE__ */ import_react4.default.createElement(import_react_native4.Text, { style: styles7.sessionCardAction }, "Resume \u2192")
15562
- ) : /* @__PURE__ */ import_react4.default.createElement(
15571
+ ) : /* @__PURE__ */ import_react4.default.createElement(import_react_native4.View, { style: styles7.sessionRow }, /* @__PURE__ */ import_react4.default.createElement(
15563
15572
  import_react_native4.TouchableOpacity,
15564
15573
  {
15565
- style: styles7.sessionCardInactive,
15574
+ style: styles7.sessionTileBlue,
15566
15575
  onPress: () => nav.push({ name: "SESSION_START" }),
15567
15576
  activeOpacity: 0.7
15568
15577
  },
15569
- /* @__PURE__ */ import_react4.default.createElement(import_react_native4.Text, { style: styles7.sessionCardIcon }, "\u{1F50D}"),
15570
- /* @__PURE__ */ import_react4.default.createElement(import_react_native4.Text, { style: styles7.sessionCardLabel }, "Start QA Session"),
15571
- /* @__PURE__ */ import_react4.default.createElement(import_react_native4.Text, { style: styles7.sessionCardArrow }, "\u2192")
15572
- ), !activeSession && nav.startAdHoc && /* @__PURE__ */ import_react4.default.createElement(
15578
+ /* @__PURE__ */ import_react4.default.createElement(import_react_native4.Text, { style: styles7.tileIcon }, "\u{1F50D}"),
15579
+ /* @__PURE__ */ import_react4.default.createElement(import_react_native4.Text, { style: styles7.tileTitle }, "Focused Session"),
15580
+ /* @__PURE__ */ import_react4.default.createElement(import_react_native4.Text, { style: styles7.tileSub }, "Set focus area & track before starting")
15581
+ ), nav.startAdHoc && /* @__PURE__ */ import_react4.default.createElement(
15573
15582
  import_react_native4.TouchableOpacity,
15574
15583
  {
15575
- style: styles7.quickTestCard,
15584
+ style: styles7.sessionTileGreen,
15576
15585
  onPress: () => nav.startAdHoc?.(),
15577
15586
  activeOpacity: 0.7
15578
15587
  },
15579
- /* @__PURE__ */ import_react4.default.createElement(import_react_native4.Text, { style: styles7.quickTestIcon }, "\u26A1"),
15580
- /* @__PURE__ */ import_react4.default.createElement(import_react_native4.View, { style: styles7.quickTestContent }, /* @__PURE__ */ import_react4.default.createElement(import_react_native4.Text, { style: styles7.quickTestTitle }, "Quick Test"), /* @__PURE__ */ import_react4.default.createElement(import_react_native4.Text, { style: styles7.quickTestSub }, "Ad hoc explore & report")),
15581
- /* @__PURE__ */ import_react4.default.createElement(import_react_native4.Text, { style: styles7.sessionCardArrow }, "\u2192")
15582
- ), !activeSession && tasks.length > 0 && /* @__PURE__ */ import_react4.default.createElement(import_react_native4.View, { style: { marginBottom: 20 } }, /* @__PURE__ */ import_react4.default.createElement(import_react_native4.Text, { style: { fontSize: 12, fontWeight: "600", color: colors.textSecondary, textTransform: "uppercase", letterSpacing: 0.5, marginBottom: 8 } }, "Task Checklist"), tasks.map((task) => /* @__PURE__ */ import_react4.default.createElement(
15588
+ /* @__PURE__ */ import_react4.default.createElement(import_react_native4.Text, { style: styles7.tileIcon }, "\u26A1"),
15589
+ /* @__PURE__ */ import_react4.default.createElement(import_react_native4.Text, { style: styles7.tileTitle }, "Quick Test"),
15590
+ /* @__PURE__ */ import_react4.default.createElement(import_react_native4.Text, { style: styles7.tileSub }, "Jump straight in \u2014 no setup needed")
15591
+ )), !activeSession && tasks.length > 0 && /* @__PURE__ */ import_react4.default.createElement(import_react_native4.View, { style: { marginBottom: 20 } }, /* @__PURE__ */ import_react4.default.createElement(import_react_native4.Text, { style: { fontSize: 12, fontWeight: "600", color: colors.textSecondary, textTransform: "uppercase", letterSpacing: 0.5, marginBottom: 8 } }, "Task Checklist"), tasks.map((task) => /* @__PURE__ */ import_react4.default.createElement(
15583
15592
  import_react_native4.TouchableOpacity,
15584
15593
  {
15585
15594
  key: task.id,
@@ -15903,7 +15912,7 @@ function createStyles() {
15903
15912
  fontSize: 13,
15904
15913
  color: colors.blue
15905
15914
  },
15906
- // Session card
15915
+ // Session card (active — running session)
15907
15916
  sessionCardActive: {
15908
15917
  flexDirection: "row",
15909
15918
  alignItems: "center",
@@ -15940,59 +15949,50 @@ function createStyles() {
15940
15949
  fontWeight: "600",
15941
15950
  color: colors.blue
15942
15951
  },
15943
- sessionCardInactive: {
15952
+ sessionCardArrow: {
15953
+ fontSize: 13,
15954
+ color: colors.textMuted
15955
+ },
15956
+ // Session start row — two side-by-side tiles
15957
+ sessionRow: {
15944
15958
  flexDirection: "row",
15945
- alignItems: "center",
15959
+ gap: 10,
15960
+ marginBottom: 16
15961
+ },
15962
+ sessionTileBlue: {
15963
+ flex: 1,
15946
15964
  backgroundColor: colors.card,
15947
15965
  borderWidth: 1,
15948
15966
  borderColor: colors.border,
15967
+ borderTopWidth: 3,
15968
+ borderTopColor: colors.blue,
15949
15969
  borderRadius: 12,
15950
15970
  padding: 12,
15951
- paddingHorizontal: 16,
15952
- gap: 12,
15953
- marginBottom: 16
15954
- },
15955
- sessionCardIcon: {
15956
- fontSize: 22
15971
+ gap: 4
15957
15972
  },
15958
- sessionCardLabel: {
15973
+ sessionTileGreen: {
15959
15974
  flex: 1,
15960
- fontSize: 14,
15961
- fontWeight: "500",
15962
- color: colors.textPrimary
15963
- },
15964
- sessionCardArrow: {
15965
- fontSize: 13,
15966
- color: colors.textMuted
15967
- },
15968
- // Quick Test card
15969
- quickTestCard: {
15970
- flexDirection: "row",
15971
- alignItems: "center",
15972
15975
  backgroundColor: colors.card,
15973
15976
  borderWidth: 1,
15974
15977
  borderColor: colors.border,
15978
+ borderTopWidth: 3,
15979
+ borderTopColor: colors.green,
15975
15980
  borderRadius: 12,
15976
15981
  padding: 12,
15977
- paddingHorizontal: 16,
15978
- gap: 12,
15979
- marginBottom: 16
15980
- },
15981
- quickTestIcon: {
15982
- fontSize: 22
15982
+ gap: 4
15983
15983
  },
15984
- quickTestContent: {
15985
- flex: 1
15984
+ tileIcon: {
15985
+ fontSize: 20
15986
15986
  },
15987
- quickTestTitle: {
15988
- fontSize: 14,
15987
+ tileTitle: {
15988
+ fontSize: 13,
15989
15989
  fontWeight: "600",
15990
15990
  color: colors.textPrimary
15991
15991
  },
15992
- quickTestSub: {
15993
- fontSize: 12,
15992
+ tileSub: {
15993
+ fontSize: 11,
15994
15994
  color: colors.textMuted,
15995
- marginTop: 2
15995
+ lineHeight: 16
15996
15996
  }
15997
15997
  });
15998
15998
  }
@@ -18885,7 +18885,9 @@ function SessionActiveScreen({ nav }) {
18885
18885
  const [elapsed, setElapsed] = (0, import_react21.useState)(0);
18886
18886
  const timerRef = (0, import_react21.useRef)(null);
18887
18887
  (0, import_react21.useEffect)(() => {
18888
- refreshSession();
18888
+ if (!activeSession) {
18889
+ refreshSession();
18890
+ }
18889
18891
  }, []);
18890
18892
  (0, import_react21.useEffect)(() => {
18891
18893
  if (timerRef.current) clearInterval(timerRef.current);
package/dist/index.mjs CHANGED
@@ -12805,7 +12805,7 @@ var BugBearClient = class {
12805
12805
  } : {
12806
12806
  // Standalone verification assignment (bug reported without a test case)
12807
12807
  id: item.original_report_id || item.id,
12808
- title: item.notes || "Bug Verification",
12808
+ title: item.notes?.replace(/^Verification:\s*/i, "") || "Bug Verification",
12809
12809
  testKey: "VERIFY",
12810
12810
  description: "Verify that the reported bug has been fixed",
12811
12811
  steps: [],
@@ -14793,6 +14793,8 @@ var BugBearContext = createContext({
14793
14793
  refreshIssueCounts: async () => {
14794
14794
  },
14795
14795
  reopenReport: async () => ({ success: false }),
14796
+ trackNavigation: () => {
14797
+ },
14796
14798
  queuedCount: 0,
14797
14799
  dashboardUrl: void 0,
14798
14800
  onError: void 0
@@ -14907,8 +14909,11 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
14907
14909
  const enhanced = contextCapture.getEnhancedContext();
14908
14910
  const enriched = {
14909
14911
  ...options,
14912
+ route: options.route ?? contextCapture.getCurrentRoute?.(),
14910
14913
  consoleLogs: options.consoleLogs ?? enhanced.consoleLogs,
14911
- networkSnapshot: options.networkSnapshot ?? enhanced.networkRequests
14914
+ networkSnapshot: options.networkSnapshot ?? enhanced.networkRequests,
14915
+ appContext: options.appContext ?? client.getAppContext(),
14916
+ deviceInfo: options.deviceInfo ?? getDeviceInfo()
14912
14917
  };
14913
14918
  const result = await client.addFinding(activeSession.id, enriched);
14914
14919
  if (result.success && result.finding) {
@@ -14916,7 +14921,10 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
14916
14921
  setActiveSession((prev) => prev ? { ...prev, findingsCount: prev.findingsCount + 1 } : null);
14917
14922
  }
14918
14923
  return result;
14919
- }, [client, activeSession]);
14924
+ }, [client, activeSession, getDeviceInfo]);
14925
+ const trackNavigation = useCallback((routeName) => {
14926
+ if (client) client.trackNavigation(routeName);
14927
+ }, [client]);
14920
14928
  const updateTesterProfile = useCallback(async (updates) => {
14921
14929
  if (!client) return { success: false, error: "Client not initialized" };
14922
14930
  const result = await client.updateTesterProfile(updates);
@@ -15194,6 +15202,7 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
15194
15202
  issueCounts,
15195
15203
  refreshIssueCounts,
15196
15204
  reopenReport,
15205
+ trackNavigation,
15197
15206
  queuedCount,
15198
15207
  dashboardUrl: config.dashboardUrl,
15199
15208
  onError: config.onError
@@ -15541,27 +15550,27 @@ function HomeScreen({ nav }) {
15541
15550
  /* @__PURE__ */ React3.createElement(View3, { style: styles7.sessionDot }),
15542
15551
  /* @__PURE__ */ React3.createElement(View3, { style: styles7.sessionCardContent }, /* @__PURE__ */ React3.createElement(Text, { style: styles7.sessionCardTitle, numberOfLines: 1 }, activeSession.focusArea || "QA Session"), /* @__PURE__ */ React3.createElement(Text, { style: styles7.sessionCardMeta }, formatTimer(sessionElapsed), " \xB7 ", sessionFindings.length, " finding", sessionFindings.length !== 1 ? "s" : "")),
15543
15552
  /* @__PURE__ */ React3.createElement(Text, { style: styles7.sessionCardAction }, "Resume \u2192")
15544
- ) : /* @__PURE__ */ React3.createElement(
15553
+ ) : /* @__PURE__ */ React3.createElement(View3, { style: styles7.sessionRow }, /* @__PURE__ */ React3.createElement(
15545
15554
  TouchableOpacity,
15546
15555
  {
15547
- style: styles7.sessionCardInactive,
15556
+ style: styles7.sessionTileBlue,
15548
15557
  onPress: () => nav.push({ name: "SESSION_START" }),
15549
15558
  activeOpacity: 0.7
15550
15559
  },
15551
- /* @__PURE__ */ React3.createElement(Text, { style: styles7.sessionCardIcon }, "\u{1F50D}"),
15552
- /* @__PURE__ */ React3.createElement(Text, { style: styles7.sessionCardLabel }, "Start QA Session"),
15553
- /* @__PURE__ */ React3.createElement(Text, { style: styles7.sessionCardArrow }, "\u2192")
15554
- ), !activeSession && nav.startAdHoc && /* @__PURE__ */ React3.createElement(
15560
+ /* @__PURE__ */ React3.createElement(Text, { style: styles7.tileIcon }, "\u{1F50D}"),
15561
+ /* @__PURE__ */ React3.createElement(Text, { style: styles7.tileTitle }, "Focused Session"),
15562
+ /* @__PURE__ */ React3.createElement(Text, { style: styles7.tileSub }, "Set focus area & track before starting")
15563
+ ), nav.startAdHoc && /* @__PURE__ */ React3.createElement(
15555
15564
  TouchableOpacity,
15556
15565
  {
15557
- style: styles7.quickTestCard,
15566
+ style: styles7.sessionTileGreen,
15558
15567
  onPress: () => nav.startAdHoc?.(),
15559
15568
  activeOpacity: 0.7
15560
15569
  },
15561
- /* @__PURE__ */ React3.createElement(Text, { style: styles7.quickTestIcon }, "\u26A1"),
15562
- /* @__PURE__ */ React3.createElement(View3, { style: styles7.quickTestContent }, /* @__PURE__ */ React3.createElement(Text, { style: styles7.quickTestTitle }, "Quick Test"), /* @__PURE__ */ React3.createElement(Text, { style: styles7.quickTestSub }, "Ad hoc explore & report")),
15563
- /* @__PURE__ */ React3.createElement(Text, { style: styles7.sessionCardArrow }, "\u2192")
15564
- ), !activeSession && tasks.length > 0 && /* @__PURE__ */ React3.createElement(View3, { style: { marginBottom: 20 } }, /* @__PURE__ */ React3.createElement(Text, { style: { fontSize: 12, fontWeight: "600", color: colors.textSecondary, textTransform: "uppercase", letterSpacing: 0.5, marginBottom: 8 } }, "Task Checklist"), tasks.map((task) => /* @__PURE__ */ React3.createElement(
15570
+ /* @__PURE__ */ React3.createElement(Text, { style: styles7.tileIcon }, "\u26A1"),
15571
+ /* @__PURE__ */ React3.createElement(Text, { style: styles7.tileTitle }, "Quick Test"),
15572
+ /* @__PURE__ */ React3.createElement(Text, { style: styles7.tileSub }, "Jump straight in \u2014 no setup needed")
15573
+ )), !activeSession && tasks.length > 0 && /* @__PURE__ */ React3.createElement(View3, { style: { marginBottom: 20 } }, /* @__PURE__ */ React3.createElement(Text, { style: { fontSize: 12, fontWeight: "600", color: colors.textSecondary, textTransform: "uppercase", letterSpacing: 0.5, marginBottom: 8 } }, "Task Checklist"), tasks.map((task) => /* @__PURE__ */ React3.createElement(
15565
15574
  TouchableOpacity,
15566
15575
  {
15567
15576
  key: task.id,
@@ -15885,7 +15894,7 @@ function createStyles() {
15885
15894
  fontSize: 13,
15886
15895
  color: colors.blue
15887
15896
  },
15888
- // Session card
15897
+ // Session card (active — running session)
15889
15898
  sessionCardActive: {
15890
15899
  flexDirection: "row",
15891
15900
  alignItems: "center",
@@ -15922,59 +15931,50 @@ function createStyles() {
15922
15931
  fontWeight: "600",
15923
15932
  color: colors.blue
15924
15933
  },
15925
- sessionCardInactive: {
15934
+ sessionCardArrow: {
15935
+ fontSize: 13,
15936
+ color: colors.textMuted
15937
+ },
15938
+ // Session start row — two side-by-side tiles
15939
+ sessionRow: {
15926
15940
  flexDirection: "row",
15927
- alignItems: "center",
15941
+ gap: 10,
15942
+ marginBottom: 16
15943
+ },
15944
+ sessionTileBlue: {
15945
+ flex: 1,
15928
15946
  backgroundColor: colors.card,
15929
15947
  borderWidth: 1,
15930
15948
  borderColor: colors.border,
15949
+ borderTopWidth: 3,
15950
+ borderTopColor: colors.blue,
15931
15951
  borderRadius: 12,
15932
15952
  padding: 12,
15933
- paddingHorizontal: 16,
15934
- gap: 12,
15935
- marginBottom: 16
15936
- },
15937
- sessionCardIcon: {
15938
- fontSize: 22
15953
+ gap: 4
15939
15954
  },
15940
- sessionCardLabel: {
15955
+ sessionTileGreen: {
15941
15956
  flex: 1,
15942
- fontSize: 14,
15943
- fontWeight: "500",
15944
- color: colors.textPrimary
15945
- },
15946
- sessionCardArrow: {
15947
- fontSize: 13,
15948
- color: colors.textMuted
15949
- },
15950
- // Quick Test card
15951
- quickTestCard: {
15952
- flexDirection: "row",
15953
- alignItems: "center",
15954
15957
  backgroundColor: colors.card,
15955
15958
  borderWidth: 1,
15956
15959
  borderColor: colors.border,
15960
+ borderTopWidth: 3,
15961
+ borderTopColor: colors.green,
15957
15962
  borderRadius: 12,
15958
15963
  padding: 12,
15959
- paddingHorizontal: 16,
15960
- gap: 12,
15961
- marginBottom: 16
15962
- },
15963
- quickTestIcon: {
15964
- fontSize: 22
15964
+ gap: 4
15965
15965
  },
15966
- quickTestContent: {
15967
- flex: 1
15966
+ tileIcon: {
15967
+ fontSize: 20
15968
15968
  },
15969
- quickTestTitle: {
15970
- fontSize: 14,
15969
+ tileTitle: {
15970
+ fontSize: 13,
15971
15971
  fontWeight: "600",
15972
15972
  color: colors.textPrimary
15973
15973
  },
15974
- quickTestSub: {
15975
- fontSize: 12,
15974
+ tileSub: {
15975
+ fontSize: 11,
15976
15976
  color: colors.textMuted,
15977
- marginTop: 2
15977
+ lineHeight: 16
15978
15978
  }
15979
15979
  });
15980
15980
  }
@@ -18867,7 +18867,9 @@ function SessionActiveScreen({ nav }) {
18867
18867
  const [elapsed, setElapsed] = useState16(0);
18868
18868
  const timerRef = useRef6(null);
18869
18869
  useEffect11(() => {
18870
- refreshSession();
18870
+ if (!activeSession) {
18871
+ refreshSession();
18872
+ }
18871
18873
  }, []);
18872
18874
  useEffect11(() => {
18873
18875
  if (timerRef.current) clearInterval(timerRef.current);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bbearai/react-native",
3
- "version": "0.10.1",
3
+ "version": "0.10.3",
4
4
  "description": "BugBear React Native components for mobile apps",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",