@buoy-gg/core 7.0.30 → 7.0.31

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 (55) hide show
  1. package/lib/commonjs/floatingMenu/AppHost.js +25 -1
  2. package/lib/commonjs/floatingMenu/DevToolsSettingsModal.js +3 -3
  3. package/lib/commonjs/floatingMenu/DevToolsSettingsModal.web.js +2 -2
  4. package/lib/commonjs/floatingMenu/FloatingDevTools.js +53 -4
  5. package/lib/commonjs/floatingMenu/MinimizedToolsContext.js +35 -7
  6. package/lib/commonjs/floatingMenu/MinimizedToolsStack.js +3 -3
  7. package/lib/commonjs/floatingMenu/ToolOpenerBridge.js +41 -0
  8. package/lib/commonjs/floatingMenu/allToolsRegistry.js +14 -0
  9. package/lib/commonjs/floatingMenu/autoDiscoverPresets.js +32 -0
  10. package/lib/commonjs/floatingMenu/autoExternalSync.js +107 -13
  11. package/lib/commonjs/floatingMenu/sync/appSyncAdapter.js +26 -5
  12. package/lib/commonjs/version.js +1 -1
  13. package/lib/module/floatingMenu/AppHost.js +25 -1
  14. package/lib/module/floatingMenu/DevToolsSettingsModal.js +3 -3
  15. package/lib/module/floatingMenu/DevToolsSettingsModal.web.js +2 -2
  16. package/lib/module/floatingMenu/FloatingDevTools.js +54 -5
  17. package/lib/module/floatingMenu/MinimizedToolsContext.js +35 -7
  18. package/lib/module/floatingMenu/MinimizedToolsStack.js +3 -3
  19. package/lib/module/floatingMenu/ToolOpenerBridge.js +37 -0
  20. package/lib/module/floatingMenu/allToolsRegistry.js +15 -1
  21. package/lib/module/floatingMenu/autoDiscoverPresets.js +32 -0
  22. package/lib/module/floatingMenu/autoExternalSync.js +105 -13
  23. package/lib/module/floatingMenu/sync/appSyncAdapter.js +26 -5
  24. package/lib/module/version.js +1 -1
  25. package/lib/typescript/commonjs/floatingMenu/AppHost.d.ts.map +1 -1
  26. package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.d.ts.map +1 -1
  27. package/lib/typescript/commonjs/floatingMenu/MinimizedToolsContext.d.ts.map +1 -1
  28. package/lib/typescript/commonjs/floatingMenu/MinimizedToolsStack.d.ts.map +1 -1
  29. package/lib/typescript/commonjs/floatingMenu/ToolOpenerBridge.d.ts +18 -0
  30. package/lib/typescript/commonjs/floatingMenu/ToolOpenerBridge.d.ts.map +1 -0
  31. package/lib/typescript/commonjs/floatingMenu/allToolsRegistry.d.ts.map +1 -1
  32. package/lib/typescript/commonjs/floatingMenu/autoDiscoverPresets.d.ts.map +1 -1
  33. package/lib/typescript/commonjs/floatingMenu/autoExternalSync.d.ts +28 -0
  34. package/lib/typescript/commonjs/floatingMenu/autoExternalSync.d.ts.map +1 -1
  35. package/lib/typescript/commonjs/floatingMenu/defaultConfig.d.ts +1 -1
  36. package/lib/typescript/commonjs/floatingMenu/defaultConfig.d.ts.map +1 -1
  37. package/lib/typescript/commonjs/floatingMenu/sync/appSyncAdapter.d.ts +5 -0
  38. package/lib/typescript/commonjs/floatingMenu/sync/appSyncAdapter.d.ts.map +1 -1
  39. package/lib/typescript/commonjs/version.d.ts +1 -1
  40. package/lib/typescript/module/floatingMenu/AppHost.d.ts.map +1 -1
  41. package/lib/typescript/module/floatingMenu/FloatingDevTools.d.ts.map +1 -1
  42. package/lib/typescript/module/floatingMenu/MinimizedToolsContext.d.ts.map +1 -1
  43. package/lib/typescript/module/floatingMenu/MinimizedToolsStack.d.ts.map +1 -1
  44. package/lib/typescript/module/floatingMenu/ToolOpenerBridge.d.ts +18 -0
  45. package/lib/typescript/module/floatingMenu/ToolOpenerBridge.d.ts.map +1 -0
  46. package/lib/typescript/module/floatingMenu/allToolsRegistry.d.ts.map +1 -1
  47. package/lib/typescript/module/floatingMenu/autoDiscoverPresets.d.ts.map +1 -1
  48. package/lib/typescript/module/floatingMenu/autoExternalSync.d.ts +28 -0
  49. package/lib/typescript/module/floatingMenu/autoExternalSync.d.ts.map +1 -1
  50. package/lib/typescript/module/floatingMenu/defaultConfig.d.ts +1 -1
  51. package/lib/typescript/module/floatingMenu/defaultConfig.d.ts.map +1 -1
  52. package/lib/typescript/module/floatingMenu/sync/appSyncAdapter.d.ts +5 -0
  53. package/lib/typescript/module/floatingMenu/sync/appSyncAdapter.d.ts.map +1 -1
  54. package/lib/typescript/module/version.d.ts +1 -1
  55. package/package.json +5 -5
@@ -964,13 +964,13 @@ const styles = StyleSheet.create({
964
964
  // Transparent so JsModal's night star field shows through everything.
965
965
  backgroundColor: "transparent"
966
966
  },
967
- // Header — the segmented control, inset so it clears the absolutely
968
- // positioned window controls on the right.
967
+ // Header — the segmented control. The window controls are cleared
968
+ // vertically by JsModal's drag-indicator strip, so this runs full width.
969
969
  headerRow: {
970
970
  flexDirection: "row",
971
971
  alignItems: "center",
972
972
  paddingLeft: night.gutter,
973
- paddingRight: 64,
973
+ paddingRight: night.gutter,
974
974
  paddingBottom: 8
975
975
  },
976
976
  // Scroll content — labeled groups on a 24pt rhythm (Everlights create screen)
@@ -801,8 +801,8 @@ export function SettingsModal({
801
801
  display: 'flex',
802
802
  alignItems: 'center',
803
803
  paddingLeft: 16,
804
- paddingRight: 64,
805
- // clears JsModal's absolutely-positioned window controls
804
+ paddingRight: 16,
805
+ // window controls are cleared vertically, not sideways
806
806
  paddingBottom: 8
807
807
  },
808
808
  children: /*#__PURE__*/_jsx("div", {
@@ -5,6 +5,7 @@ import { View, StyleSheet } from "react-native";
5
5
  import { AppHostProvider } from "./AppHost";
6
6
  import { FloatingMenu } from "./FloatingMenu.js";
7
7
  import { AppOverlay } from "./AppHost";
8
+ import { ToolOpenerBridge } from "./ToolOpenerBridge.js";
8
9
  import { autoDiscoverPresets, autoDiscoverPresetsWithCustom } from "./autoDiscoverPresets.js";
9
10
  import { sendInstallPing } from "../telemetry/installPing.js";
10
11
  import { isTelemetryEnabled } from "../Buoy.js";
@@ -16,7 +17,7 @@ import { MinimizedToolsProvider } from "./MinimizedToolsContext.js";
16
17
  import { validateDialConfig } from "./defaultConfig.js";
17
18
  import { DefaultConfigProvider } from "./DefaultConfigContext.js";
18
19
  import { LicenseManager, useProAccess, useLicense } from "@buoy-gg/license";
19
- import { AutoExternalSync, isExternalSyncAvailable } from "./autoExternalSync.js";
20
+ import { AutoExternalSync, ToolRegistryPublisher, isExternalSyncAvailable } from "./autoExternalSync.js";
20
21
  import { externalSyncOptions, shouldMountExternalSync } from "./externalSyncGate.js";
21
22
 
22
23
  /**
@@ -332,6 +333,23 @@ export const FloatingDevTools = ({
332
333
  }
333
334
  }, []);
334
335
 
336
+ // Check if react-query is installed and auto-render the ReactQueryTracker.
337
+ // Without it the event store has no QueryClient unless someone opens the
338
+ // React Query TOOL, so every other consumer of those events — the Events
339
+ // timeline most visibly — sits at a confident zero forever.
340
+ const ReactQueryTracker = useMemo(() => {
341
+ try {
342
+ // @ts-ignore - Dynamic import that may not exist
343
+ const {
344
+ ReactQueryTracker: Tracker
345
+ } = require("@buoy-gg/react-query");
346
+ return Tracker;
347
+ } catch (e) {
348
+ reportOptionalRequireError("@buoy-gg/react-query", e);
349
+ return null;
350
+ }
351
+ }, []);
352
+
335
353
  // Check if impersonate is installed and auto-render the floating banner
336
354
  const ImpersonateOverlay = useMemo(() => {
337
355
  try {
@@ -346,6 +364,23 @@ export const FloatingDevTools = ({
346
364
  }
347
365
  }, []);
348
366
 
367
+ // Check if scenarios is installed and auto-render the SIMULATED banner.
368
+ // Not optional and not suppressible: while a scenario is active the app is
369
+ // showing state that isn't real, and the banner is what stops that reaching
370
+ // a bug report or a screenshot as if it were.
371
+ const ScenariosOverlay = useMemo(() => {
372
+ try {
373
+ // @ts-ignore - Dynamic import that may not exist
374
+ const {
375
+ ScenariosOverlay: Overlay
376
+ } = require("@buoy-gg/scenarios");
377
+ return Overlay;
378
+ } catch (e) {
379
+ reportOptionalRequireError("@buoy-gg/scenarios", e);
380
+ return null;
381
+ }
382
+ }, []);
383
+
349
384
  // Check if redux is installed and auto-mount startup instrumentation.
350
385
  // Binds the store from app mount (renders nothing) so the action log, MCP
351
386
  // getState/dispatch, and desktop sync work WITHOUT the Redux tool ever
@@ -419,6 +454,17 @@ export const FloatingDevTools = ({
419
454
  isAvailable: isExternalSyncAvailable()
420
455
  });
421
456
 
457
+ // The on-device action registry is published unconditionally, separately
458
+ // from the broker socket. They used to be the same mount: `registerToolAdapters`
459
+ // lived inside AutoExternalSync, so anything driving tools from INSIDE the
460
+ // app (the Scenarios runner, Ask Buoy) got an empty registry in exactly the
461
+ // builds where sync was off, and every dispatch threw `Unknown tool`.
462
+ // Publishing the map opens no socket and contacts nothing.
463
+ const toolRegistry = /*#__PURE__*/_jsx(ToolRegistryPublisher, {
464
+ requiredEnvVars: requiredEnvVars,
465
+ customApps: syncApps
466
+ });
467
+
422
468
  // Headless (sync-only): tool adapters + route tracking + desktop sync, no
423
469
  // on-device UI. requireLicense is intentionally skipped — there's nothing
424
470
  // to gate. All hooks above already ran, so hook order is preserved, and
@@ -426,7 +472,7 @@ export const FloatingDevTools = ({
426
472
  // contacted from a shipped build that didn't ask for it).
427
473
  if (headless) {
428
474
  return /*#__PURE__*/_jsxs(_Fragment, {
429
- children: [ReduxAutoInstrument && /*#__PURE__*/_jsx(ReduxAutoInstrument, {}), ConsoleRoot && /*#__PURE__*/_jsx(ConsoleRoot, {}), RouteTracker && /*#__PURE__*/_jsx(RouteTracker, {}), syncEnabled && /*#__PURE__*/_jsx(AutoExternalSync, {
475
+ children: [ReduxAutoInstrument && /*#__PURE__*/_jsx(ReduxAutoInstrument, {}), ConsoleRoot && /*#__PURE__*/_jsx(ConsoleRoot, {}), RouteTracker && /*#__PURE__*/_jsx(RouteTracker, {}), ReactQueryTracker && /*#__PURE__*/_jsx(ReactQueryTracker, {}), toolRegistry, syncEnabled && /*#__PURE__*/_jsx(AutoExternalSync, {
430
476
  options: externalSyncOptions(externalSync),
431
477
  requiredEnvVars: requiredEnvVars,
432
478
  isPro: isLicensed,
@@ -457,7 +503,10 @@ export const FloatingDevTools = ({
457
503
  disableHints: disableHints,
458
504
  children: /*#__PURE__*/_jsx(View, {
459
505
  style: styles.container,
460
- pointerEvents: "box-none",
506
+ pointerEvents: "box-none"
507
+ // @ts-expect-error — deliberate marker prop, not part of ViewProps.
508
+ ,
509
+ __buoyDevToolsRoot: true,
461
510
  children: /*#__PURE__*/_jsxs(DevToolsVisibilityProvider, {
462
511
  children: [/*#__PURE__*/_jsx(AppHostProvider, {
463
512
  children: /*#__PURE__*/_jsxs(MinimizedToolsProvider, {
@@ -466,9 +515,9 @@ export const FloatingDevTools = ({
466
515
  ...props,
467
516
  apps: finalApps,
468
517
  environment: resolvedEnvironment
469
- }), /*#__PURE__*/_jsx(AppOverlay, {})]
518
+ }), /*#__PURE__*/_jsx(AppOverlay, {}), /*#__PURE__*/_jsx(ToolOpenerBridge, {})]
470
519
  })
471
- }), children, DebugBordersOverlay && /*#__PURE__*/_jsx(DebugBordersOverlay, {}), HighlightUpdatesOverlay && /*#__PURE__*/_jsx(HighlightUpdatesOverlay, {}), ImageOverlayOverlay && /*#__PURE__*/_jsx(ImageOverlayOverlay, {}), PerfMonitorOverlay && /*#__PURE__*/_jsx(PerfMonitorOverlay, {}), JsTopOverlay && /*#__PURE__*/_jsx(JsTopOverlay, {}), ImpersonateOverlay && /*#__PURE__*/_jsx(ImpersonateOverlay, {}), ReduxAutoInstrument && /*#__PURE__*/_jsx(ReduxAutoInstrument, {}), ConsoleRoot && /*#__PURE__*/_jsx(ConsoleRoot, {}), RouteTracker && /*#__PURE__*/_jsx(RouteTracker, {}), syncEnabled && /*#__PURE__*/_jsx(AutoExternalSync, {
520
+ }), children, DebugBordersOverlay && /*#__PURE__*/_jsx(DebugBordersOverlay, {}), HighlightUpdatesOverlay && /*#__PURE__*/_jsx(HighlightUpdatesOverlay, {}), ImageOverlayOverlay && /*#__PURE__*/_jsx(ImageOverlayOverlay, {}), PerfMonitorOverlay && /*#__PURE__*/_jsx(PerfMonitorOverlay, {}), JsTopOverlay && /*#__PURE__*/_jsx(JsTopOverlay, {}), ImpersonateOverlay && /*#__PURE__*/_jsx(ImpersonateOverlay, {}), ScenariosOverlay && /*#__PURE__*/_jsx(ScenariosOverlay, {}), ReduxAutoInstrument && /*#__PURE__*/_jsx(ReduxAutoInstrument, {}), ConsoleRoot && /*#__PURE__*/_jsx(ConsoleRoot, {}), RouteTracker && /*#__PURE__*/_jsx(RouteTracker, {}), ReactQueryTracker && /*#__PURE__*/_jsx(ReactQueryTracker, {}), toolRegistry, syncEnabled && /*#__PURE__*/_jsx(AutoExternalSync, {
472
521
  options: externalSyncOptions(externalSync),
473
522
  requiredEnvVars: requiredEnvVars,
474
523
  isPro: isLicensed,
@@ -93,6 +93,16 @@ export function MinimizedToolsProvider({
93
93
  getToolIcon
94
94
  }) {
95
95
  const [minimizedTools, setMinimizedTools] = useState([]);
96
+ /**
97
+ * A mirror of the list that can be read SYNCHRONOUSLY.
98
+ *
99
+ * `restore()` has to return the tool it removed, in the same tick, because
100
+ * its caller uses that return value to un-minimize the tool in AppHost. It
101
+ * cannot get that from `minimizedTools` (the callback is memoized with no
102
+ * deps, so it would close over a stale list) and it cannot get it from
103
+ * inside a state updater either — see the note on `restore`.
104
+ */
105
+ const minimizedToolsRef = useRef([]);
96
106
  const [isRestored, setIsRestored] = useState(false);
97
107
  const persistenceTimeoutRef = useRef(null);
98
108
  const getToolIconRef = useRef(getToolIcon);
@@ -124,6 +134,9 @@ export function MinimizedToolsProvider({
124
134
  restoreMinimizedTools();
125
135
  }, []);
126
136
 
137
+ // One assignment, every render, so the ref never lags the state it mirrors.
138
+ minimizedToolsRef.current = minimizedTools;
139
+
127
140
  // Persist minimized tools to storage with debounce
128
141
  useEffect(() => {
129
142
  if (!isRestored) return;
@@ -162,14 +175,29 @@ export function MinimizedToolsProvider({
162
175
  }];
163
176
  });
164
177
  }, []);
178
+
179
+ /**
180
+ * Take a tool out of the minimized list and hand it back to the caller.
181
+ *
182
+ * THE RETURN VALUE IS LOAD-BEARING. `MinimizedToolsStack` only calls
183
+ * `onRestore` — which is what actually un-minimizes the tool in AppHost —
184
+ * when this returns non-null. This used to assign the tool inside the
185
+ * `setMinimizedTools` updater and read it back on the next line, which
186
+ * assumes React runs updaters synchronously at the call site. Under React
187
+ * 18's automatic batching it does not: the updater runs in the render
188
+ * phase, so the caller always saw `null`, `onRestore` never fired, and
189
+ * AppHost kept the tool flagged `minimized: true`. The tool then sat in the
190
+ * rail with no way back — tapping it did nothing, and neither did opening
191
+ * it again from the dial, because AppHost already had it open. It survived
192
+ * reloads, because both stores are persisted.
193
+ *
194
+ * Reading the ref instead keeps the lookup synchronous and leaves the
195
+ * updater doing only what an updater should: deriving the next state.
196
+ */
165
197
  const restore = useCallback(instanceId => {
166
- let restoredTool = null;
167
- setMinimizedTools(current => {
168
- const index = current.findIndex(t => t.instanceId === instanceId);
169
- if (index === -1) return current;
170
- restoredTool = current[index];
171
- return current.filter(t => t.instanceId !== instanceId);
172
- });
198
+ const restoredTool = minimizedToolsRef.current.find(t => t.instanceId === instanceId) ?? null;
199
+ if (!restoredTool) return null;
200
+ setMinimizedTools(current => current.filter(t => t.instanceId !== instanceId));
173
201
  return restoredTool;
174
202
  }, []);
175
203
  const isMinimized = useCallback(id => {
@@ -28,7 +28,7 @@ const MAX_GLITCH_DELAY = 6000;
28
28
 
29
29
  function GlitchToolButton({
30
30
  tool,
31
- onPress,
31
+ onSelect,
32
32
  index
33
33
  }) {
34
34
  const glitchX = useRef(new Animated.Value(0)).current;
@@ -123,7 +123,7 @@ function GlitchToolButton({
123
123
  };
124
124
  }, [glitchX, glitchOpacity, glitchScale, index]);
125
125
  return /*#__PURE__*/_jsx(TouchableOpacity, {
126
- onPress: () => onPress(tool),
126
+ onPress: () => onSelect(tool),
127
127
  activeOpacity: 0.7,
128
128
  style: styles.toolButton,
129
129
  accessibilityLabel: `Restore ${tool.title}`,
@@ -181,7 +181,7 @@ export function MinimizedToolsStack({
181
181
  collapsedLabel: `Show ${minimizedTools.length} minimized tools`,
182
182
  children: [...minimizedTools].reverse().map((tool, index) => /*#__PURE__*/_jsx(GlitchToolButton, {
183
183
  tool: tool,
184
- onPress: handleToolPress,
184
+ onSelect: handleToolPress,
185
185
  index: index
186
186
  }, tool.instanceId))
187
187
  });
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * ToolOpenerBridge — publishes "bring a tool back on screen" to the overlays.
5
+ *
6
+ * Renders nothing. It exists only to sit INSIDE `AppHostProvider` (where the
7
+ * open-tool state lives) and hand that capability out through the global seam
8
+ * in `@buoy-gg/shared-ui`, so an overlay rendered as a sibling of the provider
9
+ * can still offer a button that opens a tool. See `toolUiBridge.ts` for why the
10
+ * overlays can't just be moved inside the provider.
11
+ *
12
+ * It only RESTORES a tool that is already open — including one that has been
13
+ * minimized, which is the case that matters (the macro recorder minimizes
14
+ * Scenarios so the tester can drive the app, then needs it back). It
15
+ * deliberately does not construct and open a tool from scratch: an opener that
16
+ * guesses at an instance is a worse failure than reporting that it couldn't,
17
+ * and every caller already has to handle `false`.
18
+ */
19
+
20
+ import { useEffect } from "react";
21
+ import { registerToolOpener } from "@buoy-gg/shared-ui";
22
+ import { useAppHost } from "./AppHost";
23
+ export function ToolOpenerBridge() {
24
+ const {
25
+ openApps,
26
+ restore
27
+ } = useAppHost();
28
+ useEffect(() => {
29
+ return registerToolOpener(toolId => {
30
+ const instance = openApps.find(app => app.id === toolId);
31
+ if (!instance) return false;
32
+ restore(instance.instanceId);
33
+ return true;
34
+ });
35
+ }, [openApps, restore]);
36
+ return null;
37
+ }
@@ -27,7 +27,7 @@ import { ImageOverlayIcon } from "@buoy-gg/shared-ui";
27
27
  // in shared/icons/*.json and generated into @buoy-gg/floating-tools-core, which
28
28
  // IS a required dependency. Unavailable items therefore render the ACTUAL tool
29
29
  // icon (just dimmed by DialIcon), and it can no longer drift from the real one.
30
- import { ZustandIcon, ZUSTAND_ICON_COLOR, JotaiIcon, JOTAI_ICON_COLOR, IMAGE_OVERLAY_ICON_COLOR, TimeMachineIcon, TIME_MACHINE_ICON_COLOR } from "@buoy-gg/floating-tools-core";
30
+ import { ZustandIcon, ZUSTAND_ICON_COLOR, JotaiIcon, JOTAI_ICON_COLOR, IMAGE_OVERLAY_ICON_COLOR, TimeMachineIcon, TIME_MACHINE_ICON_COLOR, ScenariosIcon, CopilotIcon, COPILOT_ICON_COLOR, SCENARIOS_ICON_COLOR } from "@buoy-gg/floating-tools-core";
31
31
 
32
32
  // ─── Registry entry type ──────────────────────────────────────────────────────
33
33
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -116,6 +116,20 @@ export const ALL_TOOLS_REGISTRY = [{
116
116
  renderIcon: size => /*#__PURE__*/_jsx(TimeMachineIcon, {
117
117
  size: size
118
118
  })
119
+ }, {
120
+ id: "scenarios",
121
+ name: "SCENARIOS",
122
+ color: SCENARIOS_ICON_COLOR,
123
+ renderIcon: size => /*#__PURE__*/_jsx(ScenariosIcon, {
124
+ size: size
125
+ })
126
+ }, {
127
+ id: "copilot",
128
+ name: "ASK BUOY",
129
+ color: COPILOT_ICON_COLOR,
130
+ renderIcon: size => /*#__PURE__*/_jsx(CopilotIcon, {
131
+ size: size
132
+ })
119
133
  }, {
120
134
  id: "jotai",
121
135
  name: "JOTAI",
@@ -201,6 +201,38 @@ export function autoDiscoverPresets() {
201
201
  }
202
202
  }
203
203
  },
204
+ // Scenarios
205
+ {
206
+ name: "@buoy-gg/scenarios",
207
+ loader: () => {
208
+ try {
209
+ // @ts-ignore - Dynamic import that may not exist
210
+ const {
211
+ scenariosToolPreset
212
+ } = require("@buoy-gg/scenarios");
213
+ return scenariosToolPreset;
214
+ } catch (e) {
215
+ reportOptionalRequireError("@buoy-gg/scenarios", e);
216
+ return null;
217
+ }
218
+ }
219
+ },
220
+ // Ask Buoy (AI chat)
221
+ {
222
+ name: "@buoy-gg/copilot",
223
+ loader: () => {
224
+ try {
225
+ // @ts-ignore - Dynamic import that may not exist
226
+ const {
227
+ copilotToolPreset
228
+ } = require("@buoy-gg/copilot");
229
+ return copilotToolPreset;
230
+ } catch (e) {
231
+ reportOptionalRequireError("@buoy-gg/copilot", e);
232
+ return null;
233
+ }
234
+ }
235
+ },
204
236
  // Redux DevTools
205
237
  {
206
238
  name: "@buoy-gg/redux",
@@ -19,6 +19,7 @@ import { useEffect, useMemo, useRef } from "react";
19
19
  import { Platform } from "react-native";
20
20
  import { reportOptionalRequireError } from "./optionalRequire.js";
21
21
  import { appSyncAdapter } from "./sync/appSyncAdapter.js";
22
+ import { registerToolAdapters } from "@buoy-gg/shared-ui";
22
23
 
23
24
  /* eslint-disable @typescript-eslint/no-var-requires */
24
25
 
@@ -48,6 +49,8 @@ let perfMonitorModule = null;
48
49
  let jsTopModule = null;
49
50
  let imagesModule = null;
50
51
  let assetsModule = null;
52
+ let tvRemoteModule = null;
53
+ let focusInspectorModule = null;
51
54
  let expoConstantsModule = null;
52
55
 
53
56
  // Catch bodies report through reportOptionalRequireError: silent for a
@@ -143,6 +146,16 @@ try {
143
146
  } catch (e) {
144
147
  reportOptionalRequireError("@buoy-gg/assets", e);
145
148
  }
149
+ try {
150
+ tvRemoteModule = require("@buoy-gg/tv-remote");
151
+ } catch (e) {
152
+ reportOptionalRequireError("@buoy-gg/tv-remote", e);
153
+ }
154
+ try {
155
+ focusInspectorModule = require("@buoy-gg/focus-inspector");
156
+ } catch (e) {
157
+ reportOptionalRequireError("@buoy-gg/focus-inspector", e);
158
+ }
146
159
  try {
147
160
  expoConstantsModule = require("expo-constants");
148
161
  } catch (e) {
@@ -166,6 +179,52 @@ function defaultIdentity() {
166
179
  deviceId: `${slug || "buoy"}-${Platform.OS}`
167
180
  };
168
181
  }
182
+ /**
183
+ * Build the `toolId -> sync adapter` map from whatever tool packages the app
184
+ * installed.
185
+ *
186
+ * Extracted out of AutoExternalSync so the map can be published on-device
187
+ * WITHOUT opening a broker socket. It used to be inline, which quietly welded
188
+ * the two together: `registerToolAdapters` had exactly one caller, inside a
189
+ * component that only mounts when the sync gate passes, so in any build where
190
+ * the broker path was closed the on-device registry was empty too and every
191
+ * `dispatchToolAction` threw `Unknown tool`. Anything that drives tools from
192
+ * inside the app — the Scenarios runner, Ask Buoy — needs the map without the
193
+ * socket.
194
+ */
195
+ export function useToolAdapterMap({
196
+ requiredEnvVars,
197
+ customApps
198
+ }) {
199
+ // Context-based query adapter; null when there is no QueryClientProvider
200
+ // above FloatingDevTools (or the installed @buoy-gg/react-query predates
201
+ // the hook).
202
+ const queryAdapter = reactQueryModule?.useReactQuerySyncAdapter ? reactQueryModule.useReactQuerySyncAdapter() : null;
203
+ return useToolAdapterMapInner(queryAdapter, requiredEnvVars, customApps);
204
+ }
205
+
206
+ /**
207
+ * Publish the adapter map on-device, with no socket and no external-sync
208
+ * dependency.
209
+ *
210
+ * Mounted unconditionally by FloatingDevTools. A getter is registered rather
211
+ * than a snapshot for the same reason `attachDeviceSync` does it: the memo is
212
+ * rebuilt whenever its inputs change, and a captured copy would keep
213
+ * dispatching into adapters the tree has already replaced.
214
+ */
215
+ export function ToolRegistryPublisher({
216
+ requiredEnvVars,
217
+ customApps
218
+ }) {
219
+ const tools = useToolAdapterMap({
220
+ requiredEnvVars,
221
+ customApps
222
+ });
223
+ const toolsRef = useRef(tools);
224
+ toolsRef.current = tools;
225
+ useEffect(() => registerToolAdapters(() => toolsRef.current), []);
226
+ return null;
227
+ }
169
228
  export function AutoExternalSync({
170
229
  options,
171
230
  requiredEnvVars,
@@ -178,11 +237,10 @@ export function AutoExternalSync({
178
237
  useExternalSyncSocket,
179
238
  useExternalSync
180
239
  } = externalSyncModule;
181
-
182
- // Context-based query adapter; null when there is no QueryClientProvider
183
- // above FloatingDevTools (or the installed @buoy-gg/react-query predates
184
- // the hook).
185
- const queryAdapter = reactQueryModule?.useReactQuerySyncAdapter ? reactQueryModule.useReactQuerySyncAdapter() : null;
240
+ const tools = useToolAdapterMap({
241
+ requiredEnvVars,
242
+ customApps
243
+ });
186
244
  const identity = useMemo(defaultIdentity, []);
187
245
  const deviceId = options?.deviceId ?? identity.deviceId;
188
246
  const {
@@ -228,7 +286,22 @@ export function AutoExternalSync({
228
286
  socket.off("connect", emitLicense);
229
287
  };
230
288
  }, [socket, isPro, tier, licenseKey]);
231
- const tools = useMemo(() => {
289
+ useExternalSync({
290
+ tools,
291
+ socket,
292
+ deviceId,
293
+ enableLogs: options?.enableLogs
294
+ });
295
+ return null;
296
+ }
297
+
298
+ /**
299
+ * The map itself. Split from `useToolAdapterMap` only so the react-query hook
300
+ * is called at a stable position while the memo takes its result as a plain
301
+ * dependency.
302
+ */
303
+ function useToolAdapterMapInner(queryAdapter, requiredEnvVars, customApps) {
304
+ return useMemo(() => {
232
305
  // Core's own adapter — device-level capabilities (JS-bundle reload) that
233
306
  // don't belong to any tool package. Registered unconditionally so remote
234
307
  // drivers can rely on it for every app, whatever tools are installed.
@@ -274,6 +347,26 @@ export function AutoExternalSync({
274
347
  } catch (e) {
275
348
  reportOptionalRequireError("@buoy-gg/time-machine", e);
276
349
  }
350
+ // Lazy for the same reason as time-machine: scenarios imports
351
+ // `@buoy-gg/core` for useToolHost/useToolHeader.
352
+ try {
353
+ const scenariosModule = require("@buoy-gg/scenarios");
354
+ if (scenariosModule?.scenariosSyncAdapter) {
355
+ map.scenarios = scenariosModule.scenariosSyncAdapter;
356
+ }
357
+ } catch (e) {
358
+ reportOptionalRequireError("@buoy-gg/scenarios", e);
359
+ }
360
+ // Lazy, same require-cycle reason as time-machine and scenarios: the
361
+ // copilot package imports `@buoy-gg/core` for the tool-host hooks.
362
+ try {
363
+ const copilotModule = require("@buoy-gg/copilot");
364
+ if (copilotModule?.copilotSyncAdapter) {
365
+ map.copilot = copilotModule.copilotSyncAdapter;
366
+ }
367
+ } catch (e) {
368
+ reportOptionalRequireError("@buoy-gg/copilot", e);
369
+ }
277
370
  if (envModule?.createEnvSyncAdapter) {
278
371
  map.env = envModule.createEnvSyncAdapter(requiredEnvVars ?? []);
279
372
  }
@@ -298,6 +391,12 @@ export function AutoExternalSync({
298
391
  if (assetsModule?.assetsSyncAdapter) {
299
392
  map.assets = assetsModule.assetsSyncAdapter;
300
393
  }
394
+ if (tvRemoteModule?.tvRemoteSyncAdapter) {
395
+ map["tv-remote"] = tvRemoteModule.tvRemoteSyncAdapter;
396
+ }
397
+ if (focusInspectorModule?.focusInspectorSyncAdapter) {
398
+ map["focus-inspector"] = focusInspectorModule.focusInspectorSyncAdapter;
399
+ }
301
400
 
302
401
  // Third-party custom tools that declared InstalledApp.sync. Namespaced so
303
402
  // a custom tool named "network" can't shadow the first-party adapter on
@@ -309,11 +408,4 @@ export function AutoExternalSync({
309
408
  }
310
409
  return map;
311
410
  }, [queryAdapter, requiredEnvVars, customApps]);
312
- useExternalSync({
313
- tools,
314
- socket,
315
- deviceId,
316
- enableLogs: options?.enableLogs
317
- });
318
- return null;
319
411
  }
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
 
3
+ import { Platform } from "react-native";
3
4
  import { getDevServerOrigin, resolveReloadStrategy, scheduleReloadApp } from "@buoy-gg/shared-ui";
4
5
 
5
6
  /**
@@ -12,10 +13,10 @@ import { getDevServerOrigin, resolveReloadStrategy, scheduleReloadApp } from "@b
12
13
  * Desktop, the MCP server) can count on it for every connected app — no tool
13
14
  * package, and no native peer deps, required.
14
15
  *
15
- * Today that's one thing: reloading the JS bundle. The snapshot is static
16
- * (there is nothing to stream), it just advertises whether a reload would
17
- * work and which mechanism would run, so a driver can say so up front instead
18
- * of discovering it by failing.
16
+ * Two things today: reloading the JS bundle, and what KIND of device this is.
17
+ * The snapshot is static (there is nothing to stream), it just advertises
18
+ * whether a reload would work and which mechanism would run, so a driver can
19
+ * say so up front instead of discovering it by failing.
19
20
  */
20
21
  /**
21
22
  * When THIS JS realm booted. A reload replaces the realm, so a driver that
@@ -35,13 +36,33 @@ const REALM_STARTED_AT = Date.now();
35
36
  * that learned this origin while the app was healthy.
36
37
  */
37
38
  const DEV_SERVER_ORIGIN = getDevServerOrigin();
39
+
40
+ /**
41
+ * What kind of device this is, resolved once at module load.
42
+ *
43
+ * A dashboard cannot infer this from `platform` alone: an Apple TV and an
44
+ * iPhone both report "ios", and an Android TV and a phone both report
45
+ * "android". Without it Buoy Desktop has to show every tool for every device —
46
+ * including TV-only tools on a phone, where they can never do anything.
47
+ *
48
+ * `Platform.isTVOS` is `undefined` (not `false`) on Android TV, so it is only
49
+ * ever compared against `true`.
50
+ */
51
+ const DEVICE = {
52
+ platform: Platform.OS,
53
+ isTV: Platform.isTV === true,
54
+ isTVOS: Platform.isTVOS === true
55
+ };
38
56
  export const appSyncAdapter = {
39
- version: 2,
57
+ // v3 adds `device`. Consumers must tolerate its absence — an older app on a
58
+ // newer dashboard simply reports an unknown device kind.
59
+ version: 3,
40
60
  getSnapshot: () => {
41
61
  const strategy = resolveReloadStrategy("auto");
42
62
  return {
43
63
  startedAt: REALM_STARTED_AT,
44
64
  devServerOrigin: DEV_SERVER_ORIGIN,
65
+ device: DEVICE,
45
66
  reload: {
46
67
  available: strategy !== null,
47
68
  strategy
@@ -11,4 +11,4 @@
11
11
  * Drift is prevented by a test that fails when this disagrees with
12
12
  * package.json, so a version bump that forgets this file cannot ship.
13
13
  */
14
- export const SDK_VERSION = "7.0.30";
14
+ export const SDK_VERSION = "7.0.31";
@@ -1 +1 @@
1
- {"version":3,"file":"AppHost.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/AppHost.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAQZ,SAAS,EACV,MAAM,OAAO,CAAC;AAEf,OAAO,EACL,WAAW,EAIZ,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAEL,iBAAiB,EAClB,MAAM,yBAAyB,CAAC;AAIjC,KAAK,mBAAmB,GAAG;IACzB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,KAAK,MAAM,CAAC;IACvD,KAAK,EAAE,CAAC,UAAU,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;IACrC,wDAAwD;IACxD,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,mFAAmF;IACnF,OAAO,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACxE,4CAA4C;IAC5C,WAAW,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC;CAC9C,CAAC;AAaF;;;GAGG;AACH,eAAO,MAAM,eAAe,GAAI,cAAc;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,sBA6NpE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,UAAU,2BAgBtB,CAAC;AAkHF;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,gCAsFtB,CAAC"}
1
+ {"version":3,"file":"AppHost.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/AppHost.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAQZ,SAAS,EACV,MAAM,OAAO,CAAC;AAEf,OAAO,EACL,WAAW,EAIZ,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAEL,iBAAiB,EAClB,MAAM,yBAAyB,CAAC;AAIjC,KAAK,mBAAmB,GAAG;IACzB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,KAAK,MAAM,CAAC;IACvD,KAAK,EAAE,CAAC,UAAU,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;IACrC,wDAAwD;IACxD,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,mFAAmF;IACnF,OAAO,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACxE,4CAA4C;IAC5C,WAAW,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC;CAC9C,CAAC;AAaF;;;GAGG;AACH,eAAO,MAAM,eAAe,GAAI,cAAc;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,sBA6NpE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,UAAU,2BAgBtB,CAAC;AAkHF;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,gCA8GtB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"FloatingDevTools.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/FloatingDevTools.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+D,MAAM,OAAO,CAAC;AAGpF,OAAO,EAAgB,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAMtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAQ5C,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EAEvB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,oBAAoB,CAAC;AAM5B;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,YAAY,GACpB,MAAM,GACN;IACE,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GACD;IACE,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EACR,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,OAAO,GACP,KAAK,CAAC;IACV,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEN;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC1D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;CAC1C;AAED;;;;;;GAMG;AACH,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC;IAC5E;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,IAAI,CAAC,EAAE,YAAY,EAAE,CAAC;IAEtB;;;;;;;;;;;;;;OAcG;IACH,eAAe,CAAC,EAAE,YAAY,EAAE,CAAC;IAEjC;;;;;;;;;;;;OAYG;IACH,mBAAmB,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAEzC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAE3B;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;;;;;;;;;;;;OAaG;IACH,oBAAoB,CAAC,EAAE,qBAAqB,CAAC;IAE7C;;;;;;;;;;;;;;OAcG;IACH,gBAAgB,CAAC,EAAE,iBAAiB,CAAC;IAErC;;;;;;;;;;;;;;;;OAgBG;IACH,qBAAqB,CAAC,EAAE,OAAO,oBAAoB,EAAE,WAAW,EAAE,CAAC;IAEnE;;;;;;;;;;;;;OAaG;IACH,mBAAmB,CAAC,EAAE,CAAC,WAAW,EAAE,OAAO,oBAAoB,EAAE,WAAW,KAAK,IAAI,CAAC;IAEtF;;;;;;;;;;OAUG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;;;;;;;;;;;;;;;OAkBG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAEpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;IACH,YAAY,CAAC,EAAE,OAAO,GAAG,mBAAmB,CAAC;IAE7C;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,eAAO,MAAM,gBAAgB,GAAI,0NAe9B,qBAAqB,6BA0XvB,CAAC"}
1
+ {"version":3,"file":"FloatingDevTools.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/FloatingDevTools.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+D,MAAM,OAAO,CAAC;AAGpF,OAAO,EAAgB,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAOtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAQ5C,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EAEvB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAIL,KAAK,mBAAmB,EACzB,MAAM,oBAAoB,CAAC;AAM5B;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,YAAY,GACpB,MAAM,GACN;IACE,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GACD;IACE,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EACR,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,OAAO,GACP,KAAK,CAAC;IACV,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEN;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC1D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;CAC1C;AAED;;;;;;GAMG;AACH,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC;IAC5E;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,IAAI,CAAC,EAAE,YAAY,EAAE,CAAC;IAEtB;;;;;;;;;;;;;;OAcG;IACH,eAAe,CAAC,EAAE,YAAY,EAAE,CAAC;IAEjC;;;;;;;;;;;;OAYG;IACH,mBAAmB,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAEzC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAE3B;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;;;;;;;;;;;;OAaG;IACH,oBAAoB,CAAC,EAAE,qBAAqB,CAAC;IAE7C;;;;;;;;;;;;;;OAcG;IACH,gBAAgB,CAAC,EAAE,iBAAiB,CAAC;IAErC;;;;;;;;;;;;;;;;OAgBG;IACH,qBAAqB,CAAC,EAAE,OAAO,oBAAoB,EAAE,WAAW,EAAE,CAAC;IAEnE;;;;;;;;;;;;;OAaG;IACH,mBAAmB,CAAC,EAAE,CAAC,WAAW,EAAE,OAAO,oBAAoB,EAAE,WAAW,KAAK,IAAI,CAAC;IAEtF;;;;;;;;;;OAUG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;;;;;;;;;;;;;;;OAkBG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAEpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;IACH,YAAY,CAAC,EAAE,OAAO,GAAG,mBAAmB,CAAC;IAE7C;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,eAAO,MAAM,gBAAgB,GAAI,0NAe9B,qBAAqB,6BAybvB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"MinimizedToolsContext.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/MinimizedToolsContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAOZ,SAAS,EAEV,MAAM,OAAO,CAAC;AAUf,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,iDAAiD;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,EAAE,EAAE,MAAM,CAAC;IACX,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,IAAI,EAAE,SAAS,CAAC;IAChB,gCAAgC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,WAAW,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,UAAU,CAAC,EAAE,iBAAiB,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAWD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAY3D;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED;;GAEG;AACH,UAAU,0BAA0B;IAClC,wCAAwC;IACxC,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,2EAA2E;IAC3E,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,aAAa,EAAE,aAAa,CAAC,KAAK,IAAI,CAAC;IAC7D,wEAAwE;IACxE,OAAO,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,aAAa,GAAG,IAAI,CAAC;IACtD,6CAA6C;IAC7C,WAAW,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;IACrC,8CAA8C;IAC9C,gBAAgB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,aAAa,GAAG,SAAS,CAAC;IACpE,gCAAgC;IAChC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,mBAAmB,EAAE,MAAM,YAAY,CAAC;IACxC,wDAAwD;IACxD,mBAAmB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,YAAY,GAAG,IAAI,CAAC;CAClE;AAkCD,UAAU,2BAA2B;IACnC,QAAQ,EAAE,SAAS,CAAC;IACpB,oFAAoF;IACpF,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,SAAS,CAAC;CACzC;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,QAAQ,EACR,WAAW,GACZ,EAAE,2BAA2B,qBAwJ7B;AAMD;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,0BAA0B,CAmB9D"}
1
+ {"version":3,"file":"MinimizedToolsContext.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/MinimizedToolsContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAOZ,SAAS,EAEV,MAAM,OAAO,CAAC;AAUf,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,iDAAiD;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,EAAE,EAAE,MAAM,CAAC;IACX,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,IAAI,EAAE,SAAS,CAAC;IAChB,gCAAgC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,WAAW,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,UAAU,CAAC,EAAE,iBAAiB,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAWD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAY3D;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED;;GAEG;AACH,UAAU,0BAA0B;IAClC,wCAAwC;IACxC,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,2EAA2E;IAC3E,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,aAAa,EAAE,aAAa,CAAC,KAAK,IAAI,CAAC;IAC7D,wEAAwE;IACxE,OAAO,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,aAAa,GAAG,IAAI,CAAC;IACtD,6CAA6C;IAC7C,WAAW,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;IACrC,8CAA8C;IAC9C,gBAAgB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,aAAa,GAAG,SAAS,CAAC;IACpE,gCAAgC;IAChC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,mBAAmB,EAAE,MAAM,YAAY,CAAC;IACxC,wDAAwD;IACxD,mBAAmB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,YAAY,GAAG,IAAI,CAAC;CAClE;AAkCD,UAAU,2BAA2B;IACnC,QAAQ,EAAE,SAAS,CAAC;IACpB,oFAAoF;IACpF,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,SAAS,CAAC;CACzC;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,QAAQ,EACR,WAAW,GACZ,EAAE,2BAA2B,qBAqL7B;AAMD;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,0BAA0B,CAmB9D"}
@@ -1 +1 @@
1
- {"version":3,"file":"MinimizedToolsStack.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/MinimizedToolsStack.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyC,MAAM,OAAO,CAAC;AAS9D,OAAO,EAAqB,aAAa,EAAE,MAAM,yBAAyB,CAAC;AA+K3E,MAAM,WAAW,wBAAwB;IACvC,8CAA8C;IAC9C,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,CAAC;IAC1C,0DAA0D;IAC1D,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAMD,wBAAgB,mBAAmB,CAAC,EAClC,SAAS,EACT,cAA8B,GAC/B,EAAE,wBAAwB,qBA8C1B"}
1
+ {"version":3,"file":"MinimizedToolsStack.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/MinimizedToolsStack.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyC,MAAM,OAAO,CAAC;AAS9D,OAAO,EAAqB,aAAa,EAAE,MAAM,yBAAyB,CAAC;AA2L3E,MAAM,WAAW,wBAAwB;IACvC,8CAA8C;IAC9C,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,CAAC;IAC1C,0DAA0D;IAC1D,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAMD,wBAAgB,mBAAmB,CAAC,EAClC,SAAS,EACT,cAA8B,GAC/B,EAAE,wBAAwB,qBA8C1B"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * ToolOpenerBridge — publishes "bring a tool back on screen" to the overlays.
3
+ *
4
+ * Renders nothing. It exists only to sit INSIDE `AppHostProvider` (where the
5
+ * open-tool state lives) and hand that capability out through the global seam
6
+ * in `@buoy-gg/shared-ui`, so an overlay rendered as a sibling of the provider
7
+ * can still offer a button that opens a tool. See `toolUiBridge.ts` for why the
8
+ * overlays can't just be moved inside the provider.
9
+ *
10
+ * It only RESTORES a tool that is already open — including one that has been
11
+ * minimized, which is the case that matters (the macro recorder minimizes
12
+ * Scenarios so the tester can drive the app, then needs it back). It
13
+ * deliberately does not construct and open a tool from scratch: an opener that
14
+ * guesses at an instance is a worse failure than reporting that it couldn't,
15
+ * and every caller already has to handle `false`.
16
+ */
17
+ export declare function ToolOpenerBridge(): null;
18
+ //# sourceMappingURL=ToolOpenerBridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolOpenerBridge.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/ToolOpenerBridge.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAOH,wBAAgB,gBAAgB,SAa/B"}
@@ -1 +1 @@
1
- {"version":3,"file":"allToolsRegistry.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/allToolsRegistry.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AA0C1B,MAAM,WAAW,aAAa;IAC5B,wEAAwE;IACxE,EAAE,EAAE,MAAM,CAAC;IACX,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;CAC/C;AAID;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,kBAAkB,EAAE,aAAa,EA+E7C,CAAC"}
1
+ {"version":3,"file":"allToolsRegistry.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/allToolsRegistry.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AA8C1B,MAAM,WAAW,aAAa;IAC5B,wEAAwE;IACxE,EAAE,EAAE,MAAM,CAAC;IACX,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;CAC/C;AAID;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,kBAAkB,EAAE,aAAa,EA2F7C,CAAC"}