@buoy-gg/core 7.0.40 → 7.0.42

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.
Files changed (269) hide show
  1. package/README.md +14 -85
  2. package/bin/buoy.js +20 -347
  3. package/lib/commonjs/Buoy.js +1 -107
  4. package/lib/commonjs/browserRegister.js +1 -0
  5. package/lib/commonjs/browserRegister.server.js +1 -0
  6. package/lib/commonjs/earlyHookScript.js +1 -0
  7. package/lib/commonjs/earlyNetwork.js +1 -0
  8. package/lib/commonjs/floatingMenu/AppHost.js +1 -460
  9. package/lib/commonjs/floatingMenu/AppHost.web.js +1 -364
  10. package/lib/commonjs/floatingMenu/AppHostLogic.js +1 -50
  11. package/lib/commonjs/floatingMenu/AppIcon.js +1 -91
  12. package/lib/commonjs/floatingMenu/AppIcon.web.js +1 -53
  13. package/lib/commonjs/floatingMenu/BrowserToolRuntime.js +1 -0
  14. package/lib/commonjs/floatingMenu/DefaultConfigContext.js +1 -45
  15. package/lib/commonjs/floatingMenu/DevToolsSettingsModal.js +1 -1119
  16. package/lib/commonjs/floatingMenu/DevToolsSettingsModal.shared.js +1 -0
  17. package/lib/commonjs/floatingMenu/DevToolsSettingsModal.web.js +1 -1048
  18. package/lib/commonjs/floatingMenu/DevToolsVisibilityContext.js +1 -49
  19. package/lib/commonjs/floatingMenu/FloatingDevTools.js +1 -554
  20. package/lib/commonjs/floatingMenu/FloatingDevTools.web.js +1 -401
  21. package/lib/commonjs/floatingMenu/FloatingMenu.js +1 -371
  22. package/lib/commonjs/floatingMenu/MinimizedToolsContext.js +1 -274
  23. package/lib/commonjs/floatingMenu/MinimizedToolsStack.js +1 -288
  24. package/lib/commonjs/floatingMenu/MinimizedToolsStack.web.js +1 -371
  25. package/lib/commonjs/floatingMenu/ToggleStateManager.js +1 -36
  26. package/lib/commonjs/floatingMenu/ToolHost.js +1 -281
  27. package/lib/commonjs/floatingMenu/ToolOpenerBridge.js +1 -41
  28. package/lib/commonjs/floatingMenu/autoDiscoverPresets.js +1 -461
  29. package/lib/commonjs/floatingMenu/autoExternalSync.js +1 -434
  30. package/lib/commonjs/floatingMenu/defaultConfig.js +1 -167
  31. package/lib/commonjs/floatingMenu/deviceIdentity.js +1 -173
  32. package/lib/commonjs/floatingMenu/dial/DialDevTools.js +1 -904
  33. package/lib/commonjs/floatingMenu/dial/DialDevTools.web.js +1 -821
  34. package/lib/commonjs/floatingMenu/dial/DialHyperspace.js +1 -177
  35. package/lib/commonjs/floatingMenu/dial/DialIcon.js +1 -302
  36. package/lib/commonjs/floatingMenu/dial/DialPagination.js +1 -165
  37. package/lib/commonjs/floatingMenu/dial/DialSnow.js +1 -92
  38. package/lib/commonjs/floatingMenu/dial/OnboardingTooltip.js +1 -246
  39. package/lib/commonjs/floatingMenu/dial/OnboardingTooltip.web.js +2 -147
  40. package/lib/commonjs/floatingMenu/dial/dialUsageStore.js +1 -93
  41. package/lib/commonjs/floatingMenu/dial/onboardingConstants.js +1 -42
  42. package/lib/commonjs/floatingMenu/dial/onboardingConstants.web.js +1 -42
  43. package/lib/commonjs/floatingMenu/externalSyncGate.js +1 -49
  44. package/lib/commonjs/floatingMenu/floatingTools.js +1 -42
  45. package/lib/commonjs/floatingMenu/floatingTools.web.js +1 -30
  46. package/lib/commonjs/floatingMenu/optionalRequire.js +1 -37
  47. package/lib/commonjs/floatingMenu/settingsBus.js +1 -23
  48. package/lib/commonjs/floatingMenu/sync/appSyncAdapter.js +1 -115
  49. package/lib/commonjs/floatingMenu/types.js +1 -5
  50. package/lib/commonjs/floatingMenu/useDesktopSyncStatus.js +1 -28
  51. package/lib/commonjs/floatingMenu/useDesktopSyncStatus.web.js +1 -0
  52. package/lib/commonjs/index.js +1 -291
  53. package/lib/commonjs/index.web.js +1 -150
  54. package/lib/commonjs/reactDevtoolsTypes.js +1 -0
  55. package/lib/commonjs/releaseOptIn.js +1 -0
  56. package/lib/commonjs/telemetry/installPing.js +1 -131
  57. package/lib/commonjs/toolkit.js +1 -584
  58. package/lib/commonjs/toolkitComponents.js +1 -241
  59. package/lib/commonjs/utils/autoDiscoverPresets.web.js +1 -219
  60. package/lib/commonjs/utils/createWebTool.js +1 -0
  61. package/lib/commonjs/utils/createWebTools.js +1 -0
  62. package/lib/commonjs/version.js +1 -18
  63. package/lib/module/Buoy.js +1 -102
  64. package/lib/module/browserRegister.js +1 -0
  65. package/lib/module/browserRegister.server.js +1 -0
  66. package/lib/module/earlyHookScript.js +1 -0
  67. package/lib/module/earlyNetwork.js +1 -0
  68. package/lib/module/floatingMenu/AppHost.js +1 -452
  69. package/lib/module/floatingMenu/AppHost.web.js +1 -356
  70. package/lib/module/floatingMenu/AppHostLogic.js +1 -45
  71. package/lib/module/floatingMenu/AppIcon.js +1 -84
  72. package/lib/module/floatingMenu/AppIcon.web.js +1 -47
  73. package/lib/module/floatingMenu/BrowserToolRuntime.js +1 -0
  74. package/lib/module/floatingMenu/DefaultConfigContext.js +1 -39
  75. package/lib/module/floatingMenu/DevToolsSettingsModal.js +1 -1115
  76. package/lib/module/floatingMenu/DevToolsSettingsModal.shared.js +1 -0
  77. package/lib/module/floatingMenu/DevToolsSettingsModal.web.js +1 -1055
  78. package/lib/module/floatingMenu/DevToolsVisibilityContext.js +1 -44
  79. package/lib/module/floatingMenu/FloatingDevTools.js +1 -551
  80. package/lib/module/floatingMenu/FloatingDevTools.web.js +1 -399
  81. package/lib/module/floatingMenu/FloatingMenu.js +1 -366
  82. package/lib/module/floatingMenu/MinimizedToolsContext.js +1 -266
  83. package/lib/module/floatingMenu/MinimizedToolsStack.js +1 -285
  84. package/lib/module/floatingMenu/MinimizedToolsStack.web.js +1 -368
  85. package/lib/module/floatingMenu/ToggleStateManager.js +1 -32
  86. package/lib/module/floatingMenu/ToolHost.js +1 -273
  87. package/lib/module/floatingMenu/ToolOpenerBridge.js +1 -37
  88. package/lib/module/floatingMenu/autoDiscoverPresets.js +1 -457
  89. package/lib/module/floatingMenu/autoExternalSync.js +1 -427
  90. package/lib/module/floatingMenu/defaultConfig.js +1 -158
  91. package/lib/module/floatingMenu/deviceIdentity.js +1 -163
  92. package/lib/module/floatingMenu/dial/DialDevTools.js +1 -900
  93. package/lib/module/floatingMenu/dial/DialDevTools.web.js +1 -818
  94. package/lib/module/floatingMenu/dial/DialHyperspace.js +1 -173
  95. package/lib/module/floatingMenu/dial/DialIcon.js +1 -299
  96. package/lib/module/floatingMenu/dial/DialPagination.js +1 -160
  97. package/lib/module/floatingMenu/dial/DialSnow.js +1 -90
  98. package/lib/module/floatingMenu/dial/OnboardingTooltip.js +1 -240
  99. package/lib/module/floatingMenu/dial/OnboardingTooltip.web.js +2 -142
  100. package/lib/module/floatingMenu/dial/dialUsageStore.js +1 -85
  101. package/lib/module/floatingMenu/dial/onboardingConstants.js +1 -3
  102. package/lib/module/floatingMenu/dial/onboardingConstants.web.js +1 -3
  103. package/lib/module/floatingMenu/externalSyncGate.js +1 -44
  104. package/lib/module/floatingMenu/floatingTools.js +1 -27
  105. package/lib/module/floatingMenu/floatingTools.web.js +1 -3
  106. package/lib/module/floatingMenu/optionalRequire.js +1 -33
  107. package/lib/module/floatingMenu/settingsBus.js +1 -19
  108. package/lib/module/floatingMenu/sync/appSyncAdapter.js +1 -112
  109. package/lib/module/floatingMenu/types.js +1 -3
  110. package/lib/module/floatingMenu/useDesktopSyncStatus.js +1 -25
  111. package/lib/module/floatingMenu/useDesktopSyncStatus.web.js +1 -0
  112. package/lib/module/index.js +1 -41
  113. package/lib/module/index.web.js +1 -29
  114. package/lib/module/reactDevtoolsTypes.js +1 -0
  115. package/lib/module/releaseOptIn.js +1 -0
  116. package/lib/module/telemetry/installPing.js +1 -127
  117. package/lib/module/toolkit.js +1 -62
  118. package/lib/module/toolkitComponents.js +1 -230
  119. package/lib/module/utils/autoDiscoverPresets.web.js +1 -213
  120. package/lib/module/utils/createWebTool.js +1 -0
  121. package/lib/module/utils/createWebTools.js +1 -0
  122. package/lib/module/version.js +1 -14
  123. package/lib/typescript/commonjs/browserRegister.d.ts +13 -0
  124. package/lib/typescript/commonjs/browserRegister.server.d.ts +6 -0
  125. package/lib/typescript/commonjs/earlyHookScript.d.ts +12 -0
  126. package/lib/typescript/commonjs/earlyNetwork.d.ts +52 -0
  127. package/lib/typescript/commonjs/floatingMenu/AppHost.web.d.ts +3 -3
  128. package/lib/typescript/commonjs/floatingMenu/BrowserToolRuntime.d.ts +14 -0
  129. package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.d.ts +2 -67
  130. package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.shared.d.ts +71 -0
  131. package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.web.d.ts +3 -16
  132. package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.web.d.ts +12 -6
  133. package/lib/typescript/commonjs/floatingMenu/defaultConfig.d.ts +1 -1
  134. package/lib/typescript/commonjs/floatingMenu/settingsBus.d.ts +1 -9
  135. package/lib/typescript/commonjs/floatingMenu/useDesktopSyncStatus.web.d.ts +3 -0
  136. package/lib/typescript/commonjs/index.web.d.ts +7 -0
  137. package/lib/typescript/commonjs/reactDevtoolsTypes.d.ts +8 -0
  138. package/lib/typescript/commonjs/releaseOptIn.d.ts +4 -0
  139. package/lib/typescript/commonjs/utils/autoDiscoverPresets.web.d.ts +3 -40
  140. package/lib/typescript/commonjs/utils/createWebTool.d.ts +6 -0
  141. package/lib/typescript/commonjs/utils/createWebTools.d.ts +4 -0
  142. package/lib/typescript/commonjs/version.d.ts +1 -1
  143. package/lib/typescript/module/browserRegister.d.ts +13 -0
  144. package/lib/typescript/module/browserRegister.server.d.ts +6 -0
  145. package/lib/typescript/module/earlyHookScript.d.ts +12 -0
  146. package/lib/typescript/module/earlyNetwork.d.ts +52 -0
  147. package/lib/typescript/module/floatingMenu/AppHost.web.d.ts +3 -3
  148. package/lib/typescript/module/floatingMenu/BrowserToolRuntime.d.ts +14 -0
  149. package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.d.ts +2 -67
  150. package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.shared.d.ts +71 -0
  151. package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.web.d.ts +3 -16
  152. package/lib/typescript/module/floatingMenu/FloatingDevTools.web.d.ts +12 -6
  153. package/lib/typescript/module/floatingMenu/defaultConfig.d.ts +1 -1
  154. package/lib/typescript/module/floatingMenu/settingsBus.d.ts +1 -9
  155. package/lib/typescript/module/floatingMenu/useDesktopSyncStatus.web.d.ts +3 -0
  156. package/lib/typescript/module/index.web.d.ts +7 -0
  157. package/lib/typescript/module/reactDevtoolsTypes.d.ts +8 -0
  158. package/lib/typescript/module/releaseOptIn.d.ts +4 -0
  159. package/lib/typescript/module/utils/autoDiscoverPresets.web.d.ts +3 -40
  160. package/lib/typescript/module/utils/createWebTool.d.ts +6 -0
  161. package/lib/typescript/module/utils/createWebTools.d.ts +4 -0
  162. package/lib/typescript/module/version.d.ts +1 -1
  163. package/lib/web/chunks/chunk-5SGL6QL4.mjs +1 -0
  164. package/lib/web/chunks/chunk-FROELTJH.mjs +1 -0
  165. package/lib/web/chunks/chunk-QZDVCMCT.mjs +1 -0
  166. package/lib/web/chunks/chunk-R7RGRTY5.mjs +1 -0
  167. package/lib/web/index.mjs +10 -0
  168. package/lib/web/register-server.mjs +1 -0
  169. package/lib/web/register.mjs +1 -0
  170. package/lib/web/toolkit.mjs +1 -0
  171. package/package.json +50 -12
  172. package/lib/typescript/commonjs/Buoy.d.ts.map +0 -1
  173. package/lib/typescript/commonjs/floatingMenu/AppHost.d.ts.map +0 -1
  174. package/lib/typescript/commonjs/floatingMenu/AppHost.web.d.ts.map +0 -1
  175. package/lib/typescript/commonjs/floatingMenu/AppHostLogic.d.ts.map +0 -1
  176. package/lib/typescript/commonjs/floatingMenu/AppIcon.d.ts.map +0 -1
  177. package/lib/typescript/commonjs/floatingMenu/AppIcon.web.d.ts.map +0 -1
  178. package/lib/typescript/commonjs/floatingMenu/DefaultConfigContext.d.ts.map +0 -1
  179. package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.d.ts.map +0 -1
  180. package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.web.d.ts.map +0 -1
  181. package/lib/typescript/commonjs/floatingMenu/DevToolsVisibilityContext.d.ts.map +0 -1
  182. package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.d.ts.map +0 -1
  183. package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.web.d.ts.map +0 -1
  184. package/lib/typescript/commonjs/floatingMenu/FloatingMenu.d.ts.map +0 -1
  185. package/lib/typescript/commonjs/floatingMenu/MinimizedToolsContext.d.ts.map +0 -1
  186. package/lib/typescript/commonjs/floatingMenu/MinimizedToolsStack.d.ts.map +0 -1
  187. package/lib/typescript/commonjs/floatingMenu/MinimizedToolsStack.web.d.ts.map +0 -1
  188. package/lib/typescript/commonjs/floatingMenu/ToggleStateManager.d.ts.map +0 -1
  189. package/lib/typescript/commonjs/floatingMenu/ToolHost.d.ts.map +0 -1
  190. package/lib/typescript/commonjs/floatingMenu/ToolOpenerBridge.d.ts.map +0 -1
  191. package/lib/typescript/commonjs/floatingMenu/autoDiscoverPresets.d.ts.map +0 -1
  192. package/lib/typescript/commonjs/floatingMenu/autoExternalSync.d.ts.map +0 -1
  193. package/lib/typescript/commonjs/floatingMenu/defaultConfig.d.ts.map +0 -1
  194. package/lib/typescript/commonjs/floatingMenu/deviceIdentity.d.ts.map +0 -1
  195. package/lib/typescript/commonjs/floatingMenu/dial/DialDevTools.d.ts.map +0 -1
  196. package/lib/typescript/commonjs/floatingMenu/dial/DialDevTools.web.d.ts.map +0 -1
  197. package/lib/typescript/commonjs/floatingMenu/dial/DialHyperspace.d.ts.map +0 -1
  198. package/lib/typescript/commonjs/floatingMenu/dial/DialIcon.d.ts.map +0 -1
  199. package/lib/typescript/commonjs/floatingMenu/dial/DialPagination.d.ts.map +0 -1
  200. package/lib/typescript/commonjs/floatingMenu/dial/DialSnow.d.ts.map +0 -1
  201. package/lib/typescript/commonjs/floatingMenu/dial/OnboardingTooltip.d.ts.map +0 -1
  202. package/lib/typescript/commonjs/floatingMenu/dial/OnboardingTooltip.web.d.ts.map +0 -1
  203. package/lib/typescript/commonjs/floatingMenu/dial/dialUsageStore.d.ts.map +0 -1
  204. package/lib/typescript/commonjs/floatingMenu/dial/onboardingConstants.d.ts.map +0 -1
  205. package/lib/typescript/commonjs/floatingMenu/dial/onboardingConstants.web.d.ts.map +0 -1
  206. package/lib/typescript/commonjs/floatingMenu/externalSyncGate.d.ts.map +0 -1
  207. package/lib/typescript/commonjs/floatingMenu/floatingTools.d.ts.map +0 -1
  208. package/lib/typescript/commonjs/floatingMenu/floatingTools.web.d.ts.map +0 -1
  209. package/lib/typescript/commonjs/floatingMenu/optionalRequire.d.ts.map +0 -1
  210. package/lib/typescript/commonjs/floatingMenu/settingsBus.d.ts.map +0 -1
  211. package/lib/typescript/commonjs/floatingMenu/sync/appSyncAdapter.d.ts.map +0 -1
  212. package/lib/typescript/commonjs/floatingMenu/types.d.ts.map +0 -1
  213. package/lib/typescript/commonjs/floatingMenu/useDesktopSyncStatus.d.ts.map +0 -1
  214. package/lib/typescript/commonjs/index.d.ts.map +0 -1
  215. package/lib/typescript/commonjs/index.web.d.ts.map +0 -1
  216. package/lib/typescript/commonjs/telemetry/installPing.d.ts.map +0 -1
  217. package/lib/typescript/commonjs/toolkit.d.ts.map +0 -1
  218. package/lib/typescript/commonjs/toolkitComponents.d.ts.map +0 -1
  219. package/lib/typescript/commonjs/utils/autoDiscoverPresets.web.d.ts.map +0 -1
  220. package/lib/typescript/commonjs/version.d.ts.map +0 -1
  221. package/lib/typescript/module/Buoy.d.ts.map +0 -1
  222. package/lib/typescript/module/floatingMenu/AppHost.d.ts.map +0 -1
  223. package/lib/typescript/module/floatingMenu/AppHost.web.d.ts.map +0 -1
  224. package/lib/typescript/module/floatingMenu/AppHostLogic.d.ts.map +0 -1
  225. package/lib/typescript/module/floatingMenu/AppIcon.d.ts.map +0 -1
  226. package/lib/typescript/module/floatingMenu/AppIcon.web.d.ts.map +0 -1
  227. package/lib/typescript/module/floatingMenu/DefaultConfigContext.d.ts.map +0 -1
  228. package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.d.ts.map +0 -1
  229. package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.web.d.ts.map +0 -1
  230. package/lib/typescript/module/floatingMenu/DevToolsVisibilityContext.d.ts.map +0 -1
  231. package/lib/typescript/module/floatingMenu/FloatingDevTools.d.ts.map +0 -1
  232. package/lib/typescript/module/floatingMenu/FloatingDevTools.web.d.ts.map +0 -1
  233. package/lib/typescript/module/floatingMenu/FloatingMenu.d.ts.map +0 -1
  234. package/lib/typescript/module/floatingMenu/MinimizedToolsContext.d.ts.map +0 -1
  235. package/lib/typescript/module/floatingMenu/MinimizedToolsStack.d.ts.map +0 -1
  236. package/lib/typescript/module/floatingMenu/MinimizedToolsStack.web.d.ts.map +0 -1
  237. package/lib/typescript/module/floatingMenu/ToggleStateManager.d.ts.map +0 -1
  238. package/lib/typescript/module/floatingMenu/ToolHost.d.ts.map +0 -1
  239. package/lib/typescript/module/floatingMenu/ToolOpenerBridge.d.ts.map +0 -1
  240. package/lib/typescript/module/floatingMenu/autoDiscoverPresets.d.ts.map +0 -1
  241. package/lib/typescript/module/floatingMenu/autoExternalSync.d.ts.map +0 -1
  242. package/lib/typescript/module/floatingMenu/defaultConfig.d.ts.map +0 -1
  243. package/lib/typescript/module/floatingMenu/deviceIdentity.d.ts.map +0 -1
  244. package/lib/typescript/module/floatingMenu/dial/DialDevTools.d.ts.map +0 -1
  245. package/lib/typescript/module/floatingMenu/dial/DialDevTools.web.d.ts.map +0 -1
  246. package/lib/typescript/module/floatingMenu/dial/DialHyperspace.d.ts.map +0 -1
  247. package/lib/typescript/module/floatingMenu/dial/DialIcon.d.ts.map +0 -1
  248. package/lib/typescript/module/floatingMenu/dial/DialPagination.d.ts.map +0 -1
  249. package/lib/typescript/module/floatingMenu/dial/DialSnow.d.ts.map +0 -1
  250. package/lib/typescript/module/floatingMenu/dial/OnboardingTooltip.d.ts.map +0 -1
  251. package/lib/typescript/module/floatingMenu/dial/OnboardingTooltip.web.d.ts.map +0 -1
  252. package/lib/typescript/module/floatingMenu/dial/dialUsageStore.d.ts.map +0 -1
  253. package/lib/typescript/module/floatingMenu/dial/onboardingConstants.d.ts.map +0 -1
  254. package/lib/typescript/module/floatingMenu/dial/onboardingConstants.web.d.ts.map +0 -1
  255. package/lib/typescript/module/floatingMenu/externalSyncGate.d.ts.map +0 -1
  256. package/lib/typescript/module/floatingMenu/floatingTools.d.ts.map +0 -1
  257. package/lib/typescript/module/floatingMenu/floatingTools.web.d.ts.map +0 -1
  258. package/lib/typescript/module/floatingMenu/optionalRequire.d.ts.map +0 -1
  259. package/lib/typescript/module/floatingMenu/settingsBus.d.ts.map +0 -1
  260. package/lib/typescript/module/floatingMenu/sync/appSyncAdapter.d.ts.map +0 -1
  261. package/lib/typescript/module/floatingMenu/types.d.ts.map +0 -1
  262. package/lib/typescript/module/floatingMenu/useDesktopSyncStatus.d.ts.map +0 -1
  263. package/lib/typescript/module/index.d.ts.map +0 -1
  264. package/lib/typescript/module/index.web.d.ts.map +0 -1
  265. package/lib/typescript/module/telemetry/installPing.d.ts.map +0 -1
  266. package/lib/typescript/module/toolkit.d.ts.map +0 -1
  267. package/lib/typescript/module/toolkitComponents.d.ts.map +0 -1
  268. package/lib/typescript/module/utils/autoDiscoverPresets.web.d.ts.map +0 -1
  269. package/lib/typescript/module/version.d.ts.map +0 -1
package/README.md CHANGED
@@ -1,99 +1,28 @@
1
+ <div align="center">
2
+
1
3
  # @buoy-gg/core
2
4
 
3
- [![npm version](https://img.shields.io/npm/v/@buoy-gg/core?style=flat-square&labelColor=1c1c1c&color=10B981)](https://www.npmjs.com/package/@buoy-gg/core)
4
- [![npm downloads](https://img.shields.io/npm/dm/@buoy-gg/core?style=flat-square&labelColor=1c1c1c&color=10B981&label=downloads%2Fmonth)](https://www.npmjs.com/package/@buoy-gg/core)
5
+ The floating developer-tools menu for your React Native app. Add the tool packages you need to inspect requests, app state, storage and performance.
6
+
7
+ <a href="https://buoy.gg/buoy/latest/docs/quick-start"><b>Quick start</b></a> &nbsp;·&nbsp; <a href="https://buoy.gg">buoy.gg</a> &nbsp;·&nbsp; <a href="https://github.com/Buoy-gg/buoy">All tools</a>
5
8
 
6
- Buoy adds a floating developer-tools menu to your React Native app. Install the tools you need to inspect captured requests, app state, storage, and performance.
9
+ [![npm version](https://img.shields.io/npm/v/@buoy-gg/core?style=flat-square&labelColor=10302a&color=2a9d78)](https://www.npmjs.com/package/@buoy-gg/core) [![npm downloads](https://img.shields.io/npm/dm/@buoy-gg/core?style=flat-square&labelColor=10302a&color=2a9d78&label=downloads%2Fmonth)](https://www.npmjs.com/package/@buoy-gg/core)
7
10
 
8
- ## Install and quick start
11
+ <a href="https://buoy.gg"><img src="https://raw.githubusercontent.com/Buoy-gg/buoy/main/.github/readme/film.png" alt="Play the 53-second Buoy film on buoy.gg" width="640" /></a>
9
12
 
10
- Install from your app’s directory, then sign in:
13
+ </div>
14
+
15
+ ## Install
11
16
 
12
17
  ```bash
13
18
  npm install @buoy-gg/core @buoy-gg/network
14
19
  npx --package=@buoy-gg/core buoy login
15
20
  ```
16
21
 
17
- In an Expo Router project, keep your existing navigator and providers. For example:
18
-
19
- ```tsx
20
- import { Stack } from "expo-router";
21
- import { Buoy, FloatingDevTools } from "@buoy-gg/core";
22
-
23
- Buoy.init({ licenseKey: process.env.EXPO_PUBLIC_BUOY_KEY });
24
-
25
- export default function RootLayout() {
26
- return (
27
- <>
28
- <Stack />
29
- <FloatingDevTools />
30
- </>
31
- );
32
- }
33
- ```
34
-
35
- The login command writes the Expo key to `.env.local`. Keep the navigator and menu inside your existing providers. Without Expo Router, keep your app’s root content in place of `Stack`. For React Native CLI, load the key through your app’s environment configuration and pass it to `Buoy.init`; `.env.local` is not loaded automatically.
36
-
37
- Restart the development server after installation. Open Buoy, complete any account prompt, and select Network. Trigger a new HTTP request in your app and check its URL and status. If no request appears, check whether the app used cached data or an unsupported transport.
38
-
39
- See the [Quick Start](https://buoy.gg/buoy/latest/docs/quick-start) for the full setup and [Installation](https://buoy.gg/buoy/latest/docs/installation) for requirements. Other tools may need store registration, provider context, or native dependencies.
40
-
41
- The dial shows the most recently opened tool first. Tools you haven’t opened keep their registration order.
42
-
43
- ## Tools
44
-
45
- | Tool | Package | What it does |
46
- | --- | --- | --- |
47
- | [Network](https://buoy.gg/buoy/latest/docs/tools/network) | `@buoy-gg/network` | Inspect HTTP requests captured through your React Native app’s global `fetch` and `XMLHttpRequest` hooks. Open a request to see its URL, status, headers, timing, and captured body. |
48
- | [Storage](https://buoy.gg/buoy/latest/docs/tools/storage) | `@buoy-gg/storage` | Browse and edit supported AsyncStorage, registered MMKV instances, and registered SecureStore keys inside your app. |
49
- | [Time Machine](https://buoy.gg/buoy/latest/docs/tools/time-machine) | `@buoy-gg/time-machine` | Save and restore supported client state; external side effects are not reversed. |
50
- | [Ask Buoy](https://buoy.gg/buoy/latest/docs/tools/ask-buoy) | `@buoy-gg/ask-buoy` | Use an in-app assistant with your model endpoint and configured tools. |
51
- | [Env](https://buoy.gg/buoy/latest/docs/tools/env) | `@buoy-gg/env` | Inspect runtime environment values and validate required variables. |
52
- | [Query](https://buoy.gg/buoy/latest/docs/tools/react-query) | `@buoy-gg/react-query` | Inspect the TanStack Query cache used by your app. Refetch or invalidate a query and simulate states while checking the screen that consumes it. |
53
- | [Routes](https://buoy.gg/buoy/latest/docs/tools/routes) | `@buoy-gg/route-events` | Inspect recorded navigation events and supported routes. |
54
- | [Debug Borders](https://buoy.gg/buoy/latest/docs/tools/debug-borders) | `@buoy-gg/debug-borders` | Show layout borders and component labels over your React Native app. Tap a label to inspect the component’s available properties. |
55
- | [Highlight Updates](https://buoy.gg/buoy/latest/docs/tools/highlight-updates) | `@buoy-gg/highlight-updates` | Highlight observed React component updates in development builds and inspect the available render details. |
56
- | [Bench](https://buoy.gg/buoy/latest/docs/tools/perf-monitor) | `@buoy-gg/perf-monitor` | Measure available frame-rate, CPU, and memory metrics on a device. Record comparable runs to investigate performance changes. |
57
- | [JS Top](https://buoy.gg/buoy/latest/docs/tools/js-top) | `@buoy-gg/js-top` | Task Manager for the JS thread — which timers, Promise chains & callbacks eat your JS FPS |
58
- | [Images](https://buoy.gg/buoy/latest/docs/tools/images) | `@buoy-gg/images` | Inspect image loads observed by Buoy’s supported image hooks, including timing, dimensions, and estimated decoded memory. |
59
- | [Assets](https://buoy.gg/buoy/latest/docs/tools/assets) | `@buoy-gg/assets` | Inspect assets visible to the runtime registry and, in development, the Metro dependency graph. Compare sizes and find possible duplicates. |
60
- | [Events](https://buoy.gg/buoy/latest/docs/tools/events) | `@buoy-gg/events` | Review events from configured Buoy tools in one timeline. Filter by source, inspect an event, and export a selection for debugging. |
61
- | [Console](https://buoy.gg/buoy/latest/docs/tools/console) | `@buoy-gg/console` | Read captured JavaScript console logs in your React Native app. Filter messages by level, search their contents, and inspect logged objects. |
62
- | [Sentry](https://buoy.gg/buoy/latest/docs/tools/sentry) | `@buoy-gg/sentry` | Inspect captured Sentry envelopes and diagnostic estimates. |
63
- | [Redux](https://buoy.gg/buoy/latest/docs/tools/redux) | `@buoy-gg/redux` | Inspect your connected Redux store, review captured actions and state changes, and dispatch actions from your device. |
64
- | [Zustand](https://buoy.gg/buoy/latest/docs/tools/zustand) | `@buoy-gg/zustand` | Inspect the Zustand stores you register with Buoy. Review changes, edit state, and restore retained snapshots. |
65
- | [Jotai](https://buoy.gg/buoy/latest/docs/tools/jotai) | `@buoy-gg/jotai` | Inspect registered Jotai atoms and their captured changes, with live values and per-atom history. |
66
- | [Impersonate](https://buoy.gg/buoy/latest/docs/tools/impersonate) | `@buoy-gg/impersonate` | Connect your app’s user-switching flow to Buoy so testers can switch test accounts, roles, or flags without rebuilding. |
67
- | [Overlay](https://buoy.gg/buoy/latest/docs/tools/image-overlay) | `@buoy-gg/image-overlay` | Place a reference image over your app to compare spacing, alignment, and sizing on the device. |
68
-
69
- TV tools and the iOS Simulator camera have separate [platform requirements](https://buoy.gg/buoy/latest/docs/overview).
70
-
71
- ## Desktop and AI
72
-
73
- Inspect configured tools in the floating menu on your device. You can also connect them to:
74
-
75
- - [Buoy Desktop](https://github.com/Buoy-gg/Buoy-Desktop), for desktop panels and remote actions. React Native apps need `@buoy-gg/external-sync`; follow the [connection guide](https://buoy.gg/buoy/latest/docs/desktop) and sign in to Desktop separately.
76
- - [MCP](https://buoy.gg/buoy/latest/docs/mcp), for an AI editor to inspect and act on the app. Configure both process and device accounts; data and action tools require Pro.
77
- - [Ask Buoy](https://buoy.gg/buoy/latest/docs/tools/ask-buoy), for an in-app assistant. It requires Pro, a model endpoint you configure, and the tool integrations its tasks depend on.
78
-
79
- Supported features vary by platform, build, and installed tools. [Flutter](https://buoy.gg/buoy/latest/docs/flutter/quick-start) has a separate debug-build setup.
80
-
81
- ## Account and plan requirements
82
-
83
- Use a Free or Pro Buoy account. History limits and paid features vary by tool; see [pricing](https://buoy.gg/pricing). Production access requires Pro where supported. Development-only hooks and actions remain unavailable in release builds.
84
-
85
- ## Production and connections
86
-
87
- Start with a development build. Before enabling Buoy in a shipped app, restrict access using your app’s authorization checks and review the [component reference](https://buoy.gg/buoy/latest/docs/floating-devtools). Production access requires Pro, and development-only capabilities remain unavailable.
88
-
89
- Hiding the menu is not a substitute for backend authorization. Headless mode hides the on-device UI; it still requires account admission and sync configuration. Release sync is disabled by default and must be explicitly enabled.
90
-
91
- Device sessions can travel over your LAN to the configured broker. Buoy also makes account and license requests; development telemetry is described in [Telemetry](https://buoy.gg/buoy/latest/docs/telemetry). Ask Buoy sends model requests to the endpoint you configure.
92
-
93
- ## License
22
+ Call `Buoy.init` with your key and render `<FloatingDevTools />` inside your existing providers. The login command writes the Expo key to `.env.local`; React Native CLI apps load the key through their own environment config.
94
23
 
95
- Proprietary software. © Buoy LLC. All rights reserved. See the [Terms of Service](https://buoy.gg/terms).
24
+ The [Quick start](https://buoy.gg/buoy/latest/docs/quick-start) walks through the full setup, and [every tool](https://buoy.gg/buoy/latest/docs/overview) has its own guide.
96
25
 
97
- ### Custom floating controls
26
+ ---
98
27
 
99
- The DevTools bubble uses the shared `FloatingTool` shell. Custom tools can use the same shell with `openFloatingTool`; `FloatingDevTools` already mounts the host. See the [integration guide](https://buoy.gg/buoy/latest/docs/custom-tools/floating-tools).
28
+ <sub>Part of <a href="https://buoy.gg">Buoy</a>, developer tools that live inside your app. Proprietary software. © Buoy LLC. <a href="https://buoy.gg/terms">Terms</a></sub>
package/bin/buoy.js CHANGED
@@ -1,358 +1,31 @@
1
1
  #!/usr/bin/env node
2
- /**
3
- * The `buoy` CLI.
4
- *
5
- * Ships as a bin on @buoy-gg/core rather than its own package so that
6
- * `npx buoy login` resolves from the project's own node_modules — anyone who
7
- * already installed Buoy has it, with nothing extra to install and no npm
8
- * package name to own.
9
- *
10
- * Plain CommonJS with ZERO dependencies, on purpose: it runs via npx inside
11
- * someone else's project, so every dependency would be an install-time cost and
12
- * a supply-chain surface for a tool whose entire job takes ten seconds.
13
- */
14
-
15
- 'use strict';
16
-
17
- const http = require('node:http');
18
- const fs = require('node:fs');
19
- const path = require('node:path');
20
- const crypto = require('node:crypto');
21
- const { spawn } = require('node:child_process');
22
-
23
- const SITE = process.env.BUOY_SITE_URL || 'https://buoy.gg';
24
- const LOGIN_TIMEOUT_MS = 5 * 60 * 1000;
25
-
26
- const ESC = '\x1b[';
27
- const color = (code) => (s) => `${ESC}${code}m${s}${ESC}0m`;
28
- const cyan = color(36);
29
- const green = color(32);
30
- const red = color(31);
31
- const dim = color(2);
32
- const bold = color(1);
33
-
34
- function log(msg) {
35
- process.stdout.write(`${msg}\n`);
36
- }
37
-
38
- function fail(msg) {
39
- process.stderr.write(`${red('x')} ${msg}\n`);
40
- process.exit(1);
41
- }
42
-
43
- /**
44
- * Open a URL in the user's default browser.
45
- *
46
- * Failure is not fatal: headless boxes, SSH sessions and locked-down machines
47
- * all land here, and the URL is printed regardless so it can be opened by hand.
48
- */
49
- function openBrowser(url) {
50
- const cmd =
51
- process.platform === 'darwin'
52
- ? 'open'
53
- : process.platform === 'win32'
54
- ? 'cmd'
55
- : 'xdg-open';
56
- const args = process.platform === 'win32' ? ['/c', 'start', '', url] : [url];
57
- try {
58
- spawn(cmd, args, { stdio: 'ignore', detached: true }).unref();
59
- } catch {
60
- /* the URL is printed either way */
61
- }
62
- }
63
-
64
- /**
65
- * Which env var name this project can actually read.
66
- *
67
- * Expo only inlines `EXPO_PUBLIC_`-prefixed vars into the bundle, so writing a
68
- * bare `BUOY_KEY` there produces a file that looks correct and silently does
69
- * nothing — the most likely way this whole flow could waste someone's evening.
70
- */
71
- function detectEnvVarName(root) {
72
- try {
73
- const pkgPath = path.join(root, 'package.json');
74
- if (fs.existsSync(pkgPath)) {
75
- const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
76
- const deps = Object.assign({}, pkg.dependencies, pkg.devDependencies);
77
- if (deps.expo) return 'EXPO_PUBLIC_BUOY_KEY';
78
- }
79
- if (
80
- fs.existsSync(path.join(root, 'app.config.js')) ||
81
- fs.existsSync(path.join(root, 'app.config.ts'))
82
- ) {
83
- return 'EXPO_PUBLIC_BUOY_KEY';
84
- }
85
- const appJson = path.join(root, 'app.json');
86
- if (fs.existsSync(appJson)) {
87
- const parsed = JSON.parse(fs.readFileSync(appJson, 'utf8'));
88
- if (parsed && parsed.expo) return 'EXPO_PUBLIC_BUOY_KEY';
89
- }
90
- } catch {
91
- /* fall through to the generic name */
92
- }
93
- return 'BUOY_KEY';
94
- }
95
-
96
- /**
97
- * Which env file the key belongs in.
98
- *
99
- * Expo inlines `.env.local` into EVERY bundle, release builds included, and
100
- * `npx expo export` forces NODE_ENV=production — so a free key written there
101
- * ships inside the app to every phone that installs it. Each of those phones
102
- * then validates against the license server, which is how one free account
103
- * spent the whole daily quota in a morning. `.env.development.local` is only
104
- * loaded under NODE_ENV=development, so a free key there can only ever reach
105
- * a developer's own device.
106
- *
107
- * Paid keys keep `.env.local`: a Pro customer may want the tools in a
108
- * TestFlight or QA build, and that is their call to make.
109
- */
110
- function envFileFor(varName, tier) {
111
- if (varName !== 'EXPO_PUBLIC_BUOY_KEY') return '.env.local';
112
- return tier === 'pro' || tier === 'business' ? '.env.local' : '.env.development.local';
113
- }
114
-
115
- /** Drop `NAME=...` from an env file if present. True when a line was removed. */
116
- function removeEnvVar(root, name, fileName) {
117
- const file = path.join(root, fileName);
118
- let contents;
119
- try {
120
- contents = fs.readFileSync(file, 'utf8');
121
- } catch {
122
- return false;
123
- }
124
- const pattern = new RegExp('^' + name + '=.*\\n?', 'm');
125
- if (!pattern.test(contents)) return false;
126
- fs.writeFileSync(file, contents.replace(pattern, ''), { mode: 0o600 });
127
- return true;
128
- }
129
-
130
- /** Upsert `NAME=value` in an env file, preserving everything else in the file. */
131
- function writeEnvVar(root, name, value, fileName = '.env.local') {
132
- const file = path.join(root, fileName);
133
- let contents = '';
134
- try {
135
- contents = fs.readFileSync(file, 'utf8');
136
- } catch {
137
- /* new file */
138
- }
139
-
140
- const line = `${name}=${value}`;
141
- const pattern = new RegExp('^' + name + '=.*$', 'm');
142
-
143
- if (pattern.test(contents)) {
144
- contents = contents.replace(pattern, line);
145
- } else {
146
- if (contents && !contents.endsWith('\n')) contents += '\n';
147
- contents += `${line}\n`;
148
- }
149
-
150
- fs.writeFileSync(file, contents, { mode: 0o600 });
151
- return file;
152
- }
153
-
154
- /**
155
- * Make sure the env file is ignored.
156
- *
157
- * The whole point of a per-developer key is that it identifies one person; a
158
- * key committed to a shared repo turns the count back into "repos", which is
159
- * exactly what this flow exists to avoid.
160
- */
161
- function ensureGitignored(root, fileName = '.env.local') {
162
- const file = path.join(root, '.gitignore');
163
- let contents = '';
164
- try {
165
- contents = fs.readFileSync(file, 'utf8');
166
- } catch {
167
- return false;
168
- }
169
- const exact = new RegExp('^' + fileName.replace(/\./g, '\\.') + '$', 'm');
170
- // `.env*`, `*.local` and `.env*.local` all cover both files we might write.
171
- if (exact.test(contents) || /^\.env\*|^\*\.local$|^\.env\*\.local$/m.test(contents)) return false;
172
-
173
- if (contents && !contents.endsWith('\n')) contents += '\n';
174
- contents += `\n# Buoy license key (per developer - do not commit)\n${fileName}\n`;
175
- fs.writeFileSync(file, contents);
176
- return true;
177
- }
178
-
179
- /**
180
- * Loopback auth.
181
- *
182
- * The browser does the signing in (it already holds the Clerk session), then
183
- * hands the key back to a short-lived server on 127.0.0.1. Chosen over a
184
- * device-code flow because it needs no server-side pending-code state, and over
185
- * redirecting with the key in the URL because that would write a credential
186
- * into browser history.
187
- */
188
- function awaitKeyFromBrowser() {
189
- return new Promise((resolve, reject) => {
190
- const state = crypto.randomBytes(16).toString('hex');
191
-
192
- const server = http.createServer((req, res) => {
193
- // The page runs on buoy.gg and posts here cross-origin.
194
- if (req.headers.origin === SITE) {
195
- res.setHeader('Access-Control-Allow-Origin', SITE);
196
- res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
197
- res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');
198
- // Private Network Access: Chrome is moving to require a public site to
199
- // be granted permission before it may reach loopback, via this header
200
- // on the preflight. Sending it costs nothing today and is the
201
- // difference between this flow surviving that rollout and silently
202
- // failing for every Chrome user on the same day.
203
- res.setHeader('Access-Control-Allow-Private-Network', 'true');
204
- }
205
-
206
- if (req.method === 'OPTIONS') {
207
- res.writeHead(204).end();
208
- return;
209
- }
210
- if (req.method !== 'POST') {
211
- res.writeHead(405).end();
212
- return;
213
- }
214
-
215
- let body = '';
216
- req.on('data', (chunk) => {
217
- body += chunk;
218
- // A local server that accepts unbounded input is a local server that
219
- // can be made to eat all your memory.
220
- if (body.length > 4096) req.destroy();
221
- });
222
- req.on('end', () => {
223
- let parsed = {};
224
- try {
225
- parsed = JSON.parse(body);
226
- } catch {
227
- /* handled by the check below */
228
- }
229
-
230
- // Any page in any tab can POST to localhost. The nonce is what proves
231
- // this response belongs to the login WE just started.
232
- if (parsed.state !== state || typeof parsed.key !== 'string' || !parsed.key) {
233
- res.writeHead(400).end();
234
- return;
235
- }
236
-
237
- res.writeHead(200, { 'Content-Type': 'application/json' });
238
- res.end('{"ok":true}');
239
- server.close();
240
- resolve({
241
- key: parsed.key.trim(),
242
- tier: parsed.tier || 'free',
243
- email: parsed.email || '',
244
- });
245
- });
246
- });
247
-
248
- server.on('error', reject);
249
-
250
- // Port 0 = let the OS pick. Bound to loopback only, so nothing on the
251
- // network can reach it.
252
- server.listen(0, '127.0.0.1', () => {
253
- const { port } = server.address();
254
- const url = `${SITE}/cli/login?port=${port}&state=${state}`;
255
-
256
- log('');
257
- log(` Opening ${cyan(url)}`);
258
- log(dim(' If your browser did not open, paste that URL into a browser on this computer.'));
259
- log('');
260
- log(dim(' Waiting for you to finish signing in...'));
261
-
262
- openBrowser(url);
263
- });
264
-
265
- setTimeout(() => {
266
- server.close();
267
- reject(new Error('Timed out waiting for the browser (5 minutes).'));
268
- }, LOGIN_TIMEOUT_MS).unref();
269
- });
270
- }
271
-
272
- async function login() {
273
- const root = process.cwd();
274
-
275
- let result;
276
- try {
277
- result = await awaitKeyFromBrowser();
278
- } catch (err) {
279
- fail(`${err.message}\n Nothing was written.`);
280
- return;
281
- }
282
-
283
- const varName = detectEnvVarName(root);
284
- const fileName = envFileFor(varName, result.tier);
285
- const file = writeEnvVar(root, varName, result.key, fileName);
286
- // An earlier login may have left the key in .env.local; a free key there
287
- // would still ride along into release builds.
288
- const moved = fileName !== '.env.local' && removeEnvVar(root, varName, '.env.local');
289
- const addedIgnore = ensureGitignored(root, fileName);
290
- const relative = path.relative(root, file) || fileName;
291
-
292
- log('');
293
- log(
294
- `${green('OK')} Signed in${result.email ? ' as ' + bold(result.email) : ''} - ${bold(result.tier)} tier`
295
- );
296
- log(` Wrote ${cyan(varName)} to ${cyan(relative)}`);
297
- if (moved) log(dim(` Removed the old ${varName} line from .env.local`));
298
- if (fileName === '.env.development.local') {
299
- log(dim(' Expo loads this file for `expo start` only, so the key stays out of release builds.'));
300
- }
301
- if (addedIgnore) log(dim(` Added ${fileName} to .gitignore`));
302
- log('');
303
- log(' Use it in your app:');
304
- log('');
305
- log(cyan(` Buoy.init({ licenseKey: ${varName} });`));
306
- log('');
307
- log(dim(' Swift: pass the key through BuoyConfig.licenseKey in your development build.'));
308
- log(dim(' Bare React Native does not load .env.local automatically; wire your existing env loader.'));
309
- log('');
310
- }
311
-
312
- function help() {
313
- log(`
314
- ${bold('buoy')} - React Buoy CLI
315
-
316
- ${bold('Usage')}
2
+ "use strict";const http=require("node:http");const fs=require("node:fs");const path=require("node:path");const crypto=require("node:crypto");const{spawn}=require("node:child_process");const SITE=process.env.BUOY_SITE_URL||"https://buoy.gg";const LOGIN_TIMEOUT_MS=5*60*1e3;const ESC="\x1B[";const color=e=>o=>`${ESC}${e}m${o}${ESC}0m`;const cyan=color(36);const green=color(32);const red=color(31);const dim=color(2);const bold=color(1);function log(e){process.stdout.write(`${e}
3
+ `)}function fail(e){process.stderr.write(`${red("x")} ${e}
4
+ `);process.exit(1)}function openBrowser(e){const o=process.platform==="darwin"?"open":process.platform==="win32"?"cmd":"xdg-open";const s=process.platform==="win32"?["/c","start","",e]:[e];try{spawn(o,s,{stdio:"ignore",detached:true}).unref()}catch{}}function detectEnvVarName(e){let o=null;try{const s=path.join(e,"package.json");if(fs.existsSync(s)){const i=JSON.parse(fs.readFileSync(s,"utf8"));const n=Object.assign({},i.dependencies,i.devDependencies);if(n.expo)return"EXPO_PUBLIC_BUOY_KEY";if(n.next)o="NEXT_PUBLIC_BUOY_KEY";else if(n.vite)o="VITE_BUOY_KEY"}if(fs.existsSync(path.join(e,"app.config.js"))||fs.existsSync(path.join(e,"app.config.ts"))){return"EXPO_PUBLIC_BUOY_KEY"}const t=path.join(e,"app.json");if(fs.existsSync(t)){const i=JSON.parse(fs.readFileSync(t,"utf8"));if(i&&i.expo)return"EXPO_PUBLIC_BUOY_KEY"}}catch{}return o||"BUOY_KEY"}function envFileFor(e,o){if(!["EXPO_PUBLIC_BUOY_KEY","VITE_BUOY_KEY","NEXT_PUBLIC_BUOY_KEY"].includes(e))return".env.local";return o==="pro"||o==="business"?".env.local":".env.development.local"}function removeEnvVar(e,o,s){const t=path.join(e,s);let i;try{i=fs.readFileSync(t,"utf8")}catch{return false}const n=new RegExp("^"+o+"=.*\\n?","m");if(!n.test(i))return false;fs.writeFileSync(t,i.replace(n,""),{mode:384});return true}function writeEnvVar(e,o,s,t=".env.local"){const i=path.join(e,t);let n="";try{n=fs.readFileSync(i,"utf8")}catch{}const c=`${o}=${s}`;const r=new RegExp("^"+o+"=.*$","m");if(r.test(n)){n=n.replace(r,c)}else{if(n&&!n.endsWith("\n"))n+="\n";n+=`${c}
5
+ `}fs.writeFileSync(i,n,{mode:384});return i}function ensureGitignored(e,o=".env.local"){const s=path.join(e,".gitignore");let t="";try{t=fs.readFileSync(s,"utf8")}catch{return false}const i=new RegExp("^"+o.replace(/\./g,"\\.")+"$","m");if(i.test(t)||/^\.env\*|^\*\.local$|^\.env\*\.local$/m.test(t))return false;if(t&&!t.endsWith("\n"))t+="\n";t+=`
6
+ # Buoy license key (per developer - do not commit)
7
+ ${o}
8
+ `;fs.writeFileSync(s,t);return true}function awaitKeyFromBrowser(){return new Promise((e,o)=>{const s=crypto.randomBytes(16).toString("hex");const t=http.createServer((i,n)=>{if(i.headers.origin===SITE){n.setHeader("Access-Control-Allow-Origin",SITE);n.setHeader("Access-Control-Allow-Headers","Content-Type");n.setHeader("Access-Control-Allow-Methods","POST, OPTIONS");n.setHeader("Access-Control-Allow-Private-Network","true")}if(i.method==="OPTIONS"){n.writeHead(204).end();return}if(i.method!=="POST"){n.writeHead(405).end();return}let c="";i.on("data",r=>{c+=r;if(c.length>4096)i.destroy()});i.on("end",()=>{let r={};try{r=JSON.parse(c)}catch{}if(r.state!==s||typeof r.key!=="string"||!r.key){n.writeHead(400).end();return}n.writeHead(200,{"Content-Type":"application/json"});n.end('{"ok":true}');t.close();e({key:r.key.trim(),tier:r.tier||"free",email:r.email||""})})});t.on("error",o);t.listen(0,"127.0.0.1",()=>{const{port:i}=t.address();const n=`${SITE}/cli/login?port=${i}&state=${s}`;log("");log(` Opening ${cyan(n)}`);log(dim(" If your browser did not open, paste that URL into a browser on this computer."));log("");log(dim(" Waiting for you to finish signing in..."));openBrowser(n)});setTimeout(()=>{t.close();o(new Error("Timed out waiting for the browser (5 minutes)."))},LOGIN_TIMEOUT_MS).unref()})}async function login(){const e=process.cwd();let o;try{o=await awaitKeyFromBrowser()}catch(a){fail(`${a.message}
9
+ Nothing was written.`);return}const s=detectEnvVarName(e);const t=envFileFor(s,o.tier);const i=writeEnvVar(e,s,o.key,t);const n=t!==".env.local"&&removeEnvVar(e,s,".env.local");const c=ensureGitignored(e,t);const r=path.relative(e,i)||t;log("");log(`${green("OK")} Signed in${o.email?" as "+bold(o.email):""} - ${bold(o.tier)} tier`);log(` Wrote ${cyan(s)} to ${cyan(r)}`);if(n)log(dim(` Removed the old ${s} line from .env.local`));if(t===".env.development.local"){log(dim(" This file is loaded in development, keeping the key out of production builds."))}if(c)log(dim(` Added ${t} to .gitignore`));log("");log(" Use it in your app:");log("");if(s==="VITE_BUOY_KEY"){log(cyan(" <FloatingDevTools modules={modules} licenseKey={import.meta.env.VITE_BUOY_KEY} />"));log("");log(dim(" Keep your existing tool modules and providers, then reload the web app."))}else if(s==="NEXT_PUBLIC_BUOY_KEY"){log(cyan(" <FloatingDevTools modules={modules} licenseKey={process.env.NEXT_PUBLIC_BUOY_KEY} />"));log("");log(dim(" Restart next dev so it picks up the new variable."))}else{log(cyan(` Buoy.init({ licenseKey: ${s} });`));log("");log(dim(" Swift: pass the key through BuoyConfig.licenseKey in your development build."));log(dim(" Bare React Native does not load .env.local automatically; wire your existing env loader."))}log("")}function help(){log(`
10
+ ${bold("buoy")} - React Buoy CLI
11
+
12
+ ${bold("Usage")}
317
13
  npx --package=@buoy-gg/core buoy <command>
318
14
 
319
- ${dim('(if npx picks the wrong one)')}
15
+ ${dim("(if npx picks the wrong one)")}
320
16
 
321
- ${bold('Commands')}
17
+ ${bold("Commands")}
322
18
  login Sign in and write your license key to an env file
323
19
  help Show this message
324
20
 
325
- ${bold('Notes')}
21
+ ${bold("Notes")}
326
22
  Run login from your app directory. Complete browser sign-in to receive
327
- your account key. On Expo, a free key goes to .env.development.local so
328
- it never ships in a release build; a paid key goes to .env.local. Other
329
- projects receive BUOY_KEY in .env.local and must configure their own
330
- environment loader and variable mapping.
23
+ your account key. Expo uses EXPO_PUBLIC_BUOY_KEY, Vite uses VITE_BUOY_KEY
24
+ and Next.js uses NEXT_PUBLIC_BUOY_KEY. For these, a free key goes to
25
+ .env.development.local and a paid key goes to .env.local. Other projects receive BUOY_KEY in .env.local and must
26
+ configure their own environment loader and variable mapping.
331
27
  This command does not install tools or verify a Desktop connection.
332
28
 
333
29
  Docs: ${SITE}/buoy/latest/docs/installation
334
- `);
335
- }
336
-
337
- // Only dispatch when run as a program. Without this guard, importing the file
338
- // in a test would parse the test runner's own argv and exit the process.
339
- if (require.main === module) {
340
- const command = process.argv[2];
341
-
342
- if (command === 'login') {
343
- login();
344
- } else if (!command || command === 'help' || command === '--help' || command === '-h') {
345
- help();
346
- } else {
347
- fail(`Unknown command: ${command}\n Run \`npx buoy help\` to see what is available.`);
348
- }
349
- }
350
-
351
- module.exports = {
352
- detectEnvVarName,
353
- envFileFor,
354
- writeEnvVar,
355
- removeEnvVar,
356
- ensureGitignored,
357
- awaitKeyFromBrowser,
358
- };
30
+ `)}if(require.main===module){const e=process.argv[2];if(e==="login"){login()}else if(!e||e==="help"||e==="--help"||e==="-h"){help()}else{fail(`Unknown command: ${e}
31
+ Run \`npx buoy help\` to see what is available.`)}}module.exports={detectEnvVarName,envFileFor,writeEnvVar,removeEnvVar,ensureGitignored,awaitKeyFromBrowser};
@@ -1,107 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = exports.Buoy = void 0;
7
- exports.isTelemetryEnabled = isTelemetryEnabled;
8
- var _license = require("@buoy-gg/license");
9
- /**
10
- * Buoy SDK - Main entry point for React Buoy configuration
11
- *
12
- * Initialize once at app startup, before rendering any components:
13
- *
14
- * @example
15
- * ```tsx
16
- * import { Buoy } from '@buoy-gg/core';
17
- *
18
- * Buoy.init({
19
- * licenseKey: 'YOUR_LICENSE_KEY',
20
- * });
21
- * ```
22
- */
23
-
24
- /**
25
- * Telemetry stays on unless an app explicitly opts out. Read at ping time
26
- * rather than captured, so `Buoy.init()` still wins if it runs after mount.
27
- */
28
- let telemetryEnabled = true;
29
-
30
- /** Whether the anonymous install ping is allowed to fire. */
31
- function isTelemetryEnabled() {
32
- return telemetryEnabled;
33
- }
34
-
35
- /**
36
- * Buoy SDK namespace
37
- *
38
- * Use `Buoy.init()` to configure your license key at app startup.
39
- */
40
- const Buoy = exports.Buoy = {
41
- /**
42
- * Initialize Buoy with your license key
43
- *
44
- * Call this once at app startup, before rendering FloatingDevTools.
45
- * Typically placed in App.tsx or index.js.
46
- *
47
- * @example
48
- * ```tsx
49
- * import { Buoy } from '@buoy-gg/core';
50
- *
51
- * // With hardcoded key
52
- * Buoy.init({
53
- * licenseKey: '36063C-27282E-8E73F5-55488F-2213DF-V3',
54
- * });
55
- *
56
- * // With environment variable
57
- * Buoy.init({
58
- * licenseKey: process.env.BUOY_LICENSE_KEY!,
59
- * });
60
- * ```
61
- */
62
- init(config) {
63
- if (config.telemetry === false) telemetryEnabled = false;
64
- void _license.LicenseManager.configure(config.licenseKey).catch(error => {
65
- console.warn("[Buoy] License initialization failed:", error);
66
- });
67
- },
68
- /**
69
- * Initialize Buoy asynchronously
70
- *
71
- * Use this if you need to wait for initialization to complete.
72
- *
73
- * @example
74
- * ```tsx
75
- * await Buoy.initAsync({
76
- * licenseKey: 'YOUR_LICENSE_KEY',
77
- * });
78
- * console.log('Buoy is ready!');
79
- * ```
80
- */
81
- async initAsync(config) {
82
- if (config.telemetry === false) telemetryEnabled = false;
83
- return _license.LicenseManager.configure(config.licenseKey);
84
- },
85
- /**
86
- * Check if Buoy Pro is active
87
- */
88
- isPro() {
89
- return _license.LicenseManager.isPro();
90
- },
91
- /**
92
- * Get the current license state
93
- */
94
- getState() {
95
- return _license.LicenseManager.getState();
96
- },
97
- /**
98
- * Force device re-registration (debugging helper)
99
- * Clears cached fingerprint so next init will register device again
100
- */
101
- async forceReregister() {
102
- await _license.LicenseManager.forceReregister();
103
- }
104
- };
105
-
106
- // Also export as default for flexibility
107
- var _default = exports.default = Buoy;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.default=exports.Buoy=void 0;exports.isTelemetryEnabled=isTelemetryEnabled;var _license=require("@buoy-gg/license");let telemetryEnabled=true;function isTelemetryEnabled(){return telemetryEnabled}const Buoy=exports.Buoy={init(e){if(e.telemetry===false)telemetryEnabled=false;void _license.LicenseManager.configure(e.licenseKey).catch(r=>{console.warn("[Buoy] License initialization failed:",r)})},async initAsync(e){if(e.telemetry===false)telemetryEnabled=false;return _license.LicenseManager.configure(e.licenseKey)},isPro(){return _license.LicenseManager.isPro()},getState(){return _license.LicenseManager.getState()},async forceReregister(){await _license.LicenseManager.forceReregister()}};var _default=exports.default=Buoy;
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"earlyHookScript",{enumerable:true,get:function(){return _earlyHookScript.earlyHookScript}});exports.registerBrowserDevTools=registerBrowserDevTools;var ReactDevtools=_interopRequireWildcard(require("react-devtools-core"));var _earlyNetwork=require("./earlyNetwork.js");var _releaseOptIn=require("./releaseOptIn.js");var _earlyHookScript=require("./earlyHookScript.js");function _interopRequireWildcard(u,O){if("function"==typeof WeakMap)var _=new WeakMap,r=new WeakMap;return(_interopRequireWildcard=function(e,l){if(!l&&e&&e.__esModule)return e;var t,c,i={__proto__:null,default:e};if(null===e||"object"!=typeof e&&"function"!=typeof e)return i;if(t=l?r:_){if(t.has(e))return t.get(e);t.set(e,i)}for(const n in e)"default"!==n&&{}.hasOwnProperty.call(e,n)&&((c=(t=Object.defineProperty)&&Object.getOwnPropertyDescriptor(e,n))&&(c.get||c.set)?t(i,n,c):i[n]=e[n]);return i})(u,O)}const HOOK_CALLBACKS=["onScheduleFiberRoot","onCommitFiberRoot","onPostCommitFiberRoot","onCommitFiberUnmount","setStrictMode"];function registerBrowserDevTools(u={}){if(typeof window==="undefined"||typeof document==="undefined")return false;const O=typeof __DEV__!=="undefined"?__DEV__:process.env.NODE_ENV!=="production";if(!O&&!u.enableInRelease&&!(0,_releaseOptIn.hasReleaseOptIn)())return false;(0,_earlyNetwork.installEarlyNetworkRecorder)();const _=window;const r=_.__REACT_DEVTOOLS_GLOBAL_HOOK__;const e=r&&r.supportsFiber&&!r.getFiberRoots&&!r.sub&&Object.getOwnPropertyDescriptor(_,"__REACT_DEVTOOLS_GLOBAL_HOOK__")?.configurable;if(e)delete _.__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!_.__REACT_DEVTOOLS_GLOBAL_HOOK__){const l=ReactDevtools.initialize??ReactDevtools.default?.initialize;l({appendComponentStack:false,breakOnConsoleErrors:false,showInlineWarningsAndErrors:false,hideConsoleLogsInStrictMode:false});if(e){const t=_.__REACT_DEVTOOLS_GLOBAL_HOOK__;const c=t.inject;const i=new Map;t.inject=o=>{const s=c(o);i.set(s,r.inject(o));return s};for(const o of HOOK_CALLBACKS){const s=t[o];if(typeof s!=="function")continue;t[o]=(a,...f)=>{if(i.has(a))r[o]?.(i.get(a),...f);return s(a,...f)}}const n=new Map;r.renderers?.forEach?.((o,s)=>n.set(s,c(o)));if(n.size){for(const o of HOOK_CALLBACKS){const s=r[o];r[o]=function(a,...f){const d=s?.call(this,a,...f);const p=n.get(a);if(p!==void 0)t[o]?.(p,...f);return d}}}}}return Boolean(_.__REACT_DEVTOOLS_GLOBAL_HOOK__)}registerBrowserDevTools();
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"earlyHookScript",{enumerable:true,get:function(){return _earlyHookScript.earlyHookScript}});exports.registerBrowserDevTools=registerBrowserDevTools;var _earlyHookScript=require("./earlyHookScript.js");function registerBrowserDevTools(e={}){return false}
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.earlyHookScript=void 0;const earlyHookScript=exports.earlyHookScript="(function(){var w=window;if(w.__REACT_DEVTOOLS_GLOBAL_HOOK__)return;var n=0,r=new Map(),f=function(){};w.__REACT_DEVTOOLS_GLOBAL_HOOK__={renderers:r,supportsFiber:true,inject:function(x){var i=++n;r.set(i,x);return i},onScheduleFiberRoot:f,onCommitFiberRoot:f,onPostCommitFiberRoot:f,onCommitFiberUnmount:f,setStrictMode:f,checkDCE:f}})();";
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.installEarlyNetworkRecorder=installEarlyNetworkRecorder;const MAX_RECORDS=100;function installEarlyNetworkRecorder(){if(typeof window==="undefined")return;const u=window;if(u.__BUOY_EARLY_NETWORK__)return;const d=Date.now;let f=true;const a=[];const y=c=>{a.push(c);if(a.length>MAX_RECORDS){const t=a.shift();if(t?.kind==="fetch")void t.settled.then(s=>s.clone?.body?.cancel()).catch(()=>{})}};const h=typeof window.fetch==="function"?window.fetch:void 0;if(h){window.fetch=function c(t,s){if(!f)return h.call(window,t,s);let l;try{if(t instanceof Request&&t.body&&!t.bodyUsed&&s?.body===void 0)l=t.clone()}catch{}const i=d();const o=h.call(window,t,s);const n=o.then(e=>{const r=d();const _=/event-stream|ndjson/.test(e.headers.get("content-type")??"");let w;try{if(!_)w=e.clone()}catch{}return{response:e,clone:w,headersAt:r}},e=>({error:e,headersAt:d()}));y({kind:"fetch",input:t,init:s,requestCopy:l,start:i,settled:n});return o}}if(typeof XMLHttpRequest!=="undefined"){const c=XMLHttpRequest.prototype;const{open:t,send:s,setRequestHeader:l}=c;const i=new WeakMap;c.open=function(o,n,...e){if(f)i.set(this,{method:o,url:String(n),headers:{}});return t.call(this,o,n,...e)};c.setRequestHeader=function(o,n){const e=i.get(this);if(e)e.headers[o]=n;return l.call(this,o,n)};c.send=function(o){const n=i.get(this);if(f&&n){i.delete(this);const e=d();const r=this;r.addEventListener("readystatechange",()=>{if(r.readyState===2&&r._buoyTtfb===void 0)r._buoyTtfb=d()-e;if(r.readyState===4)r._buoyEarlyEnd=d()});y({kind:"xhr",xhr:r,method:n.method,url:n.url,headers:n.headers,body:o,start:e})}return s.call(this,o)}}u.__BUOY_EARLY_NETWORK__={version:1,records:a,adopt(){f=false;return a.splice(0)}}}