@buoy-gg/core 7.0.35 → 7.0.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -10
- package/lib/commonjs/floatingMenu/MinimizedToolsStack.js +83 -4
- package/lib/commonjs/floatingMenu/MinimizedToolsStack.web.js +90 -6
- package/lib/commonjs/version.js +1 -1
- package/lib/module/floatingMenu/MinimizedToolsStack.js +88 -8
- package/lib/module/floatingMenu/MinimizedToolsStack.web.js +92 -8
- package/lib/module/version.js +1 -1
- package/lib/typescript/commonjs/floatingMenu/MinimizedToolsStack.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/MinimizedToolsStack.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/version.d.ts +1 -1
- package/lib/typescript/module/floatingMenu/MinimizedToolsStack.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/MinimizedToolsStack.web.d.ts.map +1 -1
- package/lib/typescript/module/version.d.ts +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -30,47 +30,50 @@ export default function App() {
|
|
|
30
30
|
}
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
That's the whole setup — a floating dev menu appears inside your app. Install any tool package and it auto-appears in the menu; most need zero config, a few take one line (like passing `zustandStores` or calling `watchAtoms()`). Add a `licenseKey` prop to unlock [Pro](https://buoy.gg/pricing): production builds, the MCP server, and unlimited capture.
|
|
33
|
+
That's the whole setup — a floating dev menu appears inside your app. Install any tool package and it auto-appears in the menu; most need zero config, a few take one line (like passing `zustandStores` or calling `watchAtoms()`). Add a `licenseKey` prop to unlock [Pro](https://buoy.gg/pricing): production builds, the MCP server, Ask Buoy, and unlimited capture.
|
|
34
34
|
|
|
35
|
-
## The
|
|
35
|
+
## The 21 tools
|
|
36
36
|
|
|
37
37
|
| Tool | Package | What it does |
|
|
38
38
|
| --- | --- | --- |
|
|
39
39
|
| [Network](https://buoy.gg/buoy/latest/docs/tools/network) | `@buoy-gg/network` | Every request, response, timing & error — GraphQL operations extracted and named |
|
|
40
40
|
| [Storage](https://buoy.gg/buoy/latest/docs/tools/storage) | `@buoy-gg/storage` | Browse & edit AsyncStorage, MMKV & SecureStore with change history |
|
|
41
|
+
| [Time Machine](https://buoy.gg/buoy/latest/docs/tools/time-machine) | `@buoy-gg/time-machine` | Snapshot storage, Redux, Zustand, Jotai & the query cache as restore points — jump back in one tap |
|
|
42
|
+
| [Ask Buoy](https://buoy.gg/buoy/latest/docs/tools/ask-buoy) | `@buoy-gg/ask-buoy` | An in-app AI chat that drives every tool in plain English, on your own model endpoint — with a changes bar and real undo *(beta)* |
|
|
41
43
|
| [Env](https://buoy.gg/buoy/latest/docs/tools/env) | `@buoy-gg/env` | Auto-discovers `EXPO_PUBLIC_` vars, validates types, scores config health |
|
|
42
44
|
| [Query](https://buoy.gg/buoy/latest/docs/tools/react-query) | `@buoy-gg/react-query` | TanStack Query cache — refetch, invalidate, simulate loading & error states |
|
|
43
45
|
| [Routes](https://buoy.gg/buoy/latest/docs/tools/routes) | `@buoy-gg/route-events` | Navigation events, the live stack, and the full sitemap — jump to any screen |
|
|
44
46
|
| [Debug Borders](https://buoy.gg/buoy/latest/docs/tools/debug-borders) | `@buoy-gg/debug-borders` | Depth-colored layout borders — tap any label for testID, a11y props & styles |
|
|
45
47
|
| [Highlight Updates](https://buoy.gg/buoy/latest/docs/tools/highlight-updates) | `@buoy-gg/highlight-updates` | Every render, with the cause: mount, state, props, or parent |
|
|
46
48
|
| [Bench](https://buoy.gg/buoy/latest/docs/tools/perf-monitor) | `@buoy-gg/perf-monitor` | UI/JS FPS, CPU, memory & jank on a real device — batch benchmarks, ranked reports |
|
|
49
|
+
| [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 |
|
|
50
|
+
| [Images](https://buoy.gg/buoy/latest/docs/tools/images) | `@buoy-gg/images` | Every image load with cache verdict, timing, and oversize & wasted-memory audit |
|
|
51
|
+
| [Assets](https://buoy.gg/buoy/latest/docs/tools/assets) | `@buoy-gg/assets` | Everything you ship — bundled images, fonts, video & audio with sizes, duplicates & never-loaded detection |
|
|
47
52
|
| [Events](https://buoy.gg/buoy/latest/docs/tools/events) | `@buoy-gg/events` | One timeline across every tool, with LLM-friendly export presets |
|
|
48
53
|
| [Console](https://buoy.gg/buoy/latest/docs/tools/console) | `@buoy-gg/console` | Chrome-DevTools console on device — read logs with no cable and no Metro |
|
|
54
|
+
| [Sentry](https://buoy.gg/buoy/latest/docs/tools/sentry) | `@buoy-gg/sentry` | Every envelope your app sends to Sentry, what it costs, and why an event never arrived |
|
|
49
55
|
| [Redux](https://buoy.gg/buoy/latest/docs/tools/redux) | `@buoy-gg/redux` | Inspect, dispatch & time travel — flags actions that blow the frame budget |
|
|
50
56
|
| [Zustand](https://buoy.gg/buoy/latest/docs/tools/zustand) | `@buoy-gg/zustand` | State, diffs, jump-to-state, one-tap reset — no middleware needed |
|
|
51
57
|
| [Jotai](https://buoy.gg/buoy/latest/docs/tools/jotai) | `@buoy-gg/jotai` | One `watchAtoms()` call — every event shows `prev → next` |
|
|
52
58
|
| [Impersonate](https://buoy.gg/buoy/latest/docs/tools/impersonate) | `@buoy-gg/impersonate` | Switch users, roles & flags without rebuilding |
|
|
53
59
|
| [Overlay](https://buoy.gg/buoy/latest/docs/tools/image-overlay) | `@buoy-gg/image-overlay` | Pin Figma mockups pixel-perfect over the app |
|
|
54
60
|
|
|
55
|
-
|
|
61
|
+
Two more ship for React Native TV — [TV Remote](https://buoy.gg/buoy/latest/docs/tools/tv-remote) and [Focus Inspector](https://buoy.gg/buoy/latest/docs/tools/focus-inspector) — and [Camera](https://buoy.gg/buoy/latest/docs/tools/camera) gives the iOS Simulator a working camera with no app integration at all.
|
|
56
62
|
|
|
57
|
-
|
|
58
|
-
npm i @buoy-gg/{core,network,storage,env,react-query,route-events,debug-borders,highlight-updates,perf-monitor,events,console,redux,zustand,jotai,impersonate,image-overlay}
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
## Three surfaces, one live session
|
|
63
|
+
## Four surfaces, one live session
|
|
62
64
|
|
|
63
|
-
Every tool runs inside your app's process. The phone, the desktop,
|
|
65
|
+
Every tool runs inside your app's process. The phone, the desktop, your agent and the in-app chat all see the same session, live.
|
|
64
66
|
|
|
65
67
|
- **On the phone** — tap the floating menu. Works on any device, no cable, no desktop app, no Metro.
|
|
66
68
|
- **On your desktop** — [Buoy Desktop](https://github.com/Buoy-gg/Buoy-Desktop) (free) mirrors the tools to full-screen panels on macOS, Windows & Linux, with a live FPS / CPU / memory HUD and remote control of the device. Devices connect automatically — physical phones included, no URLs to configure.
|
|
67
69
|
- **Through your agent** — the [Buoy MCP server](https://buoy.gg/buoy/latest/docs/mcp) gives Claude Code, Cursor, or any MCP editor structured tool calls into the running app: read live state, tap real buttons, run benchmarks on a physical device.
|
|
70
|
+
- **In plain English** — [Ask Buoy](https://buoy.gg/buoy/latest/docs/tools/ask-buoy) *(beta)* puts an AI chat inside the app that drives the same tools for QA, support and product. Your model endpoint, your key; nothing goes through Buoy.
|
|
68
71
|
|
|
69
72
|
## Free vs Pro
|
|
70
73
|
|
|
71
74
|
Every tool is **free** on every tier — only how much history each keeps changes. A free key (`npx buoy login`, no card) restores the full free tier.
|
|
72
75
|
|
|
73
|
-
**Pro** unlocks production builds, the MCP server, and unlimited capture. Activate with one prop:
|
|
76
|
+
**Pro** unlocks production builds, the MCP server, Ask Buoy, and unlimited capture. Activate with one prop:
|
|
74
77
|
|
|
75
78
|
```tsx
|
|
76
79
|
<FloatingDevTools licenseKey="YOUR_LICENSE_KEY" />
|
|
@@ -10,9 +10,50 @@ var _sharedUi = require("@buoy-gg/shared-ui");
|
|
|
10
10
|
var _MinimizedToolsContext = require("./MinimizedToolsContext.js");
|
|
11
11
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
12
12
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
13
|
+
/**
|
|
14
|
+
* A hidden tool's "I need you". See `setToolAttention` in shared-ui — the tool
|
|
15
|
+
* publishes, the rail draws. Read through useSyncExternalStore so a badge set
|
|
16
|
+
* from inside a minimized sheet lands on the chip without the rail polling.
|
|
17
|
+
*/function useToolAttention(toolId) {
|
|
18
|
+
return (0, _react.useSyncExternalStore)(_sharedUi.subscribeToolAttention, () => (0, _sharedUi.getToolAttention)(toolId), () => (0, _sharedUi.getToolAttention)(toolId));
|
|
19
|
+
}
|
|
20
|
+
const ATTENTION_COLORS = {
|
|
21
|
+
needsInput: "#FF8329",
|
|
22
|
+
done: "#20C997",
|
|
23
|
+
failed: "#FF3B30"
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/** needsInput outranks failed outranks done — the peek shows the one that matters most. */
|
|
27
|
+
const ATTENTION_RANK = {
|
|
28
|
+
needsInput: 3,
|
|
29
|
+
failed: 2,
|
|
30
|
+
done: 1
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/** The strongest attention across every minimized tool, for the folded peek. */
|
|
34
|
+
function useStrongestAttention(toolIds) {
|
|
35
|
+
const key = toolIds.join("|");
|
|
36
|
+
return (0, _react.useSyncExternalStore)(_sharedUi.subscribeToolAttention, () => strongest(key), () => strongest(key));
|
|
37
|
+
}
|
|
38
|
+
const strongestCache = new Map();
|
|
39
|
+
function strongest(key) {
|
|
40
|
+
let best = null;
|
|
41
|
+
for (const id of key ? key.split("|") : []) {
|
|
42
|
+
const a = (0, _sharedUi.getToolAttention)(id);
|
|
43
|
+
if (a && (!best || ATTENTION_RANK[a.kind] > ATTENTION_RANK[best.kind])) best = a;
|
|
44
|
+
}
|
|
45
|
+
// Same value → same object, or useSyncExternalStore re-renders forever.
|
|
46
|
+
const prev = strongestCache.get(key);
|
|
47
|
+
if (prev && best && prev.kind === best.kind && prev.label === best.label) return prev;
|
|
48
|
+
if (!prev && !best) return null;
|
|
49
|
+
strongestCache.set(key, best);
|
|
50
|
+
return best;
|
|
51
|
+
}
|
|
52
|
+
|
|
13
53
|
// ============================================================================
|
|
14
54
|
// Constants
|
|
15
55
|
// ============================================================================
|
|
56
|
+
|
|
16
57
|
const PEEK_HEIGHT = 28;
|
|
17
58
|
const TOOLBAR_WIDTH = 44;
|
|
18
59
|
const TOOL_ITEM_SIZE = 32;
|
|
@@ -35,6 +76,7 @@ function GlitchToolButton({
|
|
|
35
76
|
onSelect,
|
|
36
77
|
index
|
|
37
78
|
}) {
|
|
79
|
+
const attention = useToolAttention(tool.id);
|
|
38
80
|
const glitchX = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current;
|
|
39
81
|
const glitchOpacity = (0, _react.useRef)(new _reactNative.Animated.Value(1)).current;
|
|
40
82
|
const glitchScale = (0, _react.useRef)(new _reactNative.Animated.Value(1)).current;
|
|
@@ -126,14 +168,14 @@ function GlitchToolButton({
|
|
|
126
168
|
clearTimeout(timeoutId);
|
|
127
169
|
};
|
|
128
170
|
}, [glitchX, glitchOpacity, glitchScale, index]);
|
|
129
|
-
return /*#__PURE__*/(0, _jsxRuntime.
|
|
171
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
|
|
130
172
|
onPress: () => onSelect(tool),
|
|
131
173
|
activeOpacity: 0.7,
|
|
132
174
|
style: styles.toolButton,
|
|
133
|
-
accessibilityLabel: `Restore ${tool.title}`,
|
|
175
|
+
accessibilityLabel: attention ? `${tool.title} — ${attention.label}. Restore` : `Restore ${tool.title}`,
|
|
134
176
|
accessibilityRole: "button",
|
|
135
177
|
testID: `buoy-dock-restore-${tool.id}`,
|
|
136
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
|
|
178
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
|
|
137
179
|
style: {
|
|
138
180
|
opacity: glitchOpacity,
|
|
139
181
|
transform: [{
|
|
@@ -143,7 +185,17 @@ function GlitchToolButton({
|
|
|
143
185
|
}]
|
|
144
186
|
},
|
|
145
187
|
children: tool.icon
|
|
146
|
-
})
|
|
188
|
+
}), attention ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
189
|
+
style: [styles.badge, {
|
|
190
|
+
backgroundColor: ATTENTION_COLORS[attention.kind]
|
|
191
|
+
}],
|
|
192
|
+
testID: `buoy-dock-badge-${tool.id}-${attention.kind}`,
|
|
193
|
+
pointerEvents: "none",
|
|
194
|
+
children: attention.kind === "needsInput" ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
195
|
+
style: styles.badgeText,
|
|
196
|
+
children: "!"
|
|
197
|
+
}) : null
|
|
198
|
+
}) : null]
|
|
147
199
|
});
|
|
148
200
|
}
|
|
149
201
|
|
|
@@ -163,6 +215,7 @@ function MinimizedToolsStack({
|
|
|
163
215
|
minimizedTools,
|
|
164
216
|
restore
|
|
165
217
|
} = (0, _MinimizedToolsContext.useMinimizedTools)();
|
|
218
|
+
const peekAttention = useStrongestAttention(minimizedTools.map(t => t.id));
|
|
166
219
|
|
|
167
220
|
// Calculate expanded height based on number of tools
|
|
168
221
|
const expandedHeight = TOOLBAR_PADDING + minimizedTools.length * TOOL_ITEM_SIZE + (minimizedTools.length - 1) * ICON_GAP + ICON_GAP + COLLAPSE_BUTTON_SIZE + 4;
|
|
@@ -186,6 +239,11 @@ function MinimizedToolsStack({
|
|
|
186
239
|
collapsedLabel: `Show ${minimizedTools.length} minimized tools`,
|
|
187
240
|
testID: "buoy-dock-peek",
|
|
188
241
|
collapseTestID: "buoy-dock-collapse",
|
|
242
|
+
attention: peekAttention ? {
|
|
243
|
+
color: ATTENTION_COLORS[peekAttention.kind],
|
|
244
|
+
glyph: peekAttention.kind === "needsInput" ? "!" : undefined,
|
|
245
|
+
label: peekAttention.label
|
|
246
|
+
} : null,
|
|
189
247
|
children: [...minimizedTools].reverse().map((tool, index) => /*#__PURE__*/(0, _jsxRuntime.jsx)(GlitchToolButton, {
|
|
190
248
|
tool: tool,
|
|
191
249
|
onSelect: handleToolPress,
|
|
@@ -205,5 +263,26 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
205
263
|
alignItems: "center",
|
|
206
264
|
justifyContent: "center",
|
|
207
265
|
backgroundColor: "transparent"
|
|
266
|
+
},
|
|
267
|
+
// Top-right of the chip. Needs-input carries a glyph; done/failed are a dot —
|
|
268
|
+
// the colour says which, the glyph says "act".
|
|
269
|
+
badge: {
|
|
270
|
+
position: "absolute",
|
|
271
|
+
top: 0,
|
|
272
|
+
right: 0,
|
|
273
|
+
minWidth: 12,
|
|
274
|
+
height: 12,
|
|
275
|
+
borderRadius: 6,
|
|
276
|
+
paddingHorizontal: 2,
|
|
277
|
+
alignItems: "center",
|
|
278
|
+
justifyContent: "center",
|
|
279
|
+
borderWidth: 1.5,
|
|
280
|
+
borderColor: "#0C0C0C"
|
|
281
|
+
},
|
|
282
|
+
badgeText: {
|
|
283
|
+
color: "#000",
|
|
284
|
+
fontSize: 8,
|
|
285
|
+
fontWeight: "800",
|
|
286
|
+
lineHeight: 9
|
|
208
287
|
}
|
|
209
288
|
});
|
|
@@ -24,6 +24,39 @@ var _jsxRuntime = require("react/jsx-runtime");
|
|
|
24
24
|
* used before this replaced it.
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
|
+
/** Twin of the native hook — see MinimizedToolsStack.tsx. */
|
|
28
|
+
function useToolAttention(toolId) {
|
|
29
|
+
return (0, _react.useSyncExternalStore)(_sharedUi.subscribeToolAttention, () => (0, _sharedUi.getToolAttention)(toolId), () => (0, _sharedUi.getToolAttention)(toolId));
|
|
30
|
+
}
|
|
31
|
+
const ATTENTION_COLORS = {
|
|
32
|
+
needsInput: '#FF8329',
|
|
33
|
+
done: '#20C997',
|
|
34
|
+
failed: '#FF3B30'
|
|
35
|
+
};
|
|
36
|
+
const ATTENTION_RANK = {
|
|
37
|
+
needsInput: 3,
|
|
38
|
+
failed: 2,
|
|
39
|
+
done: 1
|
|
40
|
+
};
|
|
41
|
+
const strongestCache = new Map();
|
|
42
|
+
function strongest(key) {
|
|
43
|
+
let best = null;
|
|
44
|
+
for (const id of key ? key.split('|') : []) {
|
|
45
|
+
const a = (0, _sharedUi.getToolAttention)(id);
|
|
46
|
+
if (a && (!best || ATTENTION_RANK[a.kind] > ATTENTION_RANK[best.kind])) best = a;
|
|
47
|
+
}
|
|
48
|
+
const prev = strongestCache.get(key);
|
|
49
|
+
if (prev && best && prev.kind === best.kind && prev.label === best.label) return prev;
|
|
50
|
+
if (!prev && !best) return null;
|
|
51
|
+
strongestCache.set(key, best);
|
|
52
|
+
return best;
|
|
53
|
+
}
|
|
54
|
+
/** Twin of the native hook: the strongest attention across the folded dock. */
|
|
55
|
+
function useStrongestAttention(toolIds) {
|
|
56
|
+
const key = toolIds.join('|');
|
|
57
|
+
return (0, _react.useSyncExternalStore)(_sharedUi.subscribeToolAttention, () => strongest(key), () => strongest(key));
|
|
58
|
+
}
|
|
59
|
+
|
|
27
60
|
// native MinimizedToolsStack.tsx constants
|
|
28
61
|
const PEEK_HEIGHT = 28;
|
|
29
62
|
const TOOL_ITEM_SIZE = 32;
|
|
@@ -61,11 +94,13 @@ function ChevronGlyph({
|
|
|
61
94
|
});
|
|
62
95
|
}
|
|
63
96
|
function GlitchToolButton({
|
|
97
|
+
id,
|
|
64
98
|
title,
|
|
65
99
|
icon,
|
|
66
100
|
index,
|
|
67
101
|
onPress
|
|
68
102
|
}) {
|
|
103
|
+
const attention = useToolAttention(id);
|
|
69
104
|
const innerRef = (0, _react.useRef)(null);
|
|
70
105
|
(0, _react.useEffect)(() => {
|
|
71
106
|
let mounted = true;
|
|
@@ -116,9 +151,9 @@ function GlitchToolButton({
|
|
|
116
151
|
clearTimeout(timer);
|
|
117
152
|
};
|
|
118
153
|
}, [index]);
|
|
119
|
-
return /*#__PURE__*/(0, _jsxRuntime.
|
|
154
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)("button", {
|
|
120
155
|
type: "button",
|
|
121
|
-
"aria-label": `Restore ${title}`,
|
|
156
|
+
"aria-label": attention ? `${title} — ${attention.label}. Restore` : `Restore ${title}`,
|
|
122
157
|
onClick: onPress,
|
|
123
158
|
style: {
|
|
124
159
|
width: TOOL_ITEM_SIZE,
|
|
@@ -129,9 +164,10 @@ function GlitchToolButton({
|
|
|
129
164
|
background: 'none',
|
|
130
165
|
border: 'none',
|
|
131
166
|
padding: 0,
|
|
132
|
-
cursor: 'pointer'
|
|
167
|
+
cursor: 'pointer',
|
|
168
|
+
position: 'relative'
|
|
133
169
|
},
|
|
134
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
170
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
135
171
|
ref: innerRef,
|
|
136
172
|
style: {
|
|
137
173
|
display: 'flex',
|
|
@@ -139,7 +175,30 @@ function GlitchToolButton({
|
|
|
139
175
|
justifyContent: 'center'
|
|
140
176
|
},
|
|
141
177
|
children: icon
|
|
142
|
-
})
|
|
178
|
+
}), attention ? /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
|
|
179
|
+
"aria-hidden": true,
|
|
180
|
+
"data-testid": `buoy-dock-badge-${id}-${attention.kind}`,
|
|
181
|
+
style: {
|
|
182
|
+
position: 'absolute',
|
|
183
|
+
top: 0,
|
|
184
|
+
right: 0,
|
|
185
|
+
minWidth: 12,
|
|
186
|
+
height: 12,
|
|
187
|
+
borderRadius: 6,
|
|
188
|
+
padding: '0 2px',
|
|
189
|
+
boxSizing: 'border-box',
|
|
190
|
+
background: ATTENTION_COLORS[attention.kind],
|
|
191
|
+
border: '1.5px solid #0C0C0C',
|
|
192
|
+
color: '#000',
|
|
193
|
+
fontSize: 8,
|
|
194
|
+
fontWeight: 800,
|
|
195
|
+
lineHeight: '9px',
|
|
196
|
+
display: 'flex',
|
|
197
|
+
alignItems: 'center',
|
|
198
|
+
justifyContent: 'center'
|
|
199
|
+
},
|
|
200
|
+
children: attention.kind === 'needsInput' ? '!' : ''
|
|
201
|
+
}) : null]
|
|
143
202
|
});
|
|
144
203
|
}
|
|
145
204
|
function MinimizedToolsStack({
|
|
@@ -152,6 +211,7 @@ function MinimizedToolsStack({
|
|
|
152
211
|
const minimized = openApps.filter(app => app.minimized && app.launchMode !== 'toggle-only');
|
|
153
212
|
const [isExpanded, setIsExpanded] = (0, _react.useState)(false);
|
|
154
213
|
const [isStateRestored, setIsStateRestored] = (0, _react.useState)(false);
|
|
214
|
+
const peekAttention = useStrongestAttention(minimized.map(app => app.id));
|
|
155
215
|
|
|
156
216
|
// Restore + persist the expanded flag (native ExpandablePopover persistState).
|
|
157
217
|
(0, _react.useEffect)(() => {
|
|
@@ -219,6 +279,7 @@ function MinimizedToolsStack({
|
|
|
219
279
|
boxSizing: 'border-box'
|
|
220
280
|
},
|
|
221
281
|
children: [[...minimized].reverse().map((app, index) => /*#__PURE__*/(0, _jsxRuntime.jsx)(GlitchToolButton, {
|
|
282
|
+
id: app.id,
|
|
222
283
|
title: app.title || app.id,
|
|
223
284
|
icon: app.icon ?? /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
|
|
224
285
|
style: {
|
|
@@ -273,7 +334,30 @@ function MinimizedToolsStack({
|
|
|
273
334
|
pointerEvents: isExpanded ? 'none' : 'auto',
|
|
274
335
|
...frame
|
|
275
336
|
},
|
|
276
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(ChevronGlyph, {}),
|
|
337
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(ChevronGlyph, {}), peekAttention ? /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
|
|
338
|
+
"aria-hidden": true,
|
|
339
|
+
"data-testid": `buoy-dock-peek-attention`,
|
|
340
|
+
style: {
|
|
341
|
+
position: 'absolute',
|
|
342
|
+
top: 2,
|
|
343
|
+
right: 2,
|
|
344
|
+
minWidth: 11,
|
|
345
|
+
height: 11,
|
|
346
|
+
borderRadius: 6,
|
|
347
|
+
padding: '0 2px',
|
|
348
|
+
boxSizing: 'border-box',
|
|
349
|
+
background: ATTENTION_COLORS[peekAttention.kind],
|
|
350
|
+
border: '1.5px solid #0C0C0C',
|
|
351
|
+
color: '#000',
|
|
352
|
+
fontSize: 8,
|
|
353
|
+
fontWeight: 800,
|
|
354
|
+
lineHeight: '9px',
|
|
355
|
+
display: 'flex',
|
|
356
|
+
alignItems: 'center',
|
|
357
|
+
justifyContent: 'center'
|
|
358
|
+
},
|
|
359
|
+
children: peekAttention.kind === 'needsInput' ? '!' : ''
|
|
360
|
+
}) : null, minimized.length > 1 && /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
|
|
277
361
|
style: {
|
|
278
362
|
fontSize: 9,
|
|
279
363
|
fontWeight: 600,
|
package/lib/commonjs/version.js
CHANGED
|
@@ -15,4 +15,4 @@ exports.SDK_VERSION = void 0;
|
|
|
15
15
|
* Drift is prevented by a test that fails when this disagrees with
|
|
16
16
|
* package.json, so a version bump that forgets this file cannot ship.
|
|
17
17
|
*/
|
|
18
|
-
const SDK_VERSION = exports.SDK_VERSION = "7.0.
|
|
18
|
+
const SDK_VERSION = exports.SDK_VERSION = "7.0.36";
|
|
@@ -1,14 +1,56 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
import React, { useCallback, useEffect, useRef } from "react";
|
|
4
|
-
import { Animated, TouchableOpacity, StyleSheet, Easing } from "react-native";
|
|
5
|
-
import { ExpandablePopover } from "@buoy-gg/shared-ui";
|
|
3
|
+
import React, { useCallback, useEffect, useRef, useSyncExternalStore } from "react";
|
|
4
|
+
import { Animated, TouchableOpacity, View, Text, StyleSheet, Easing } from "react-native";
|
|
5
|
+
import { ExpandablePopover, getToolAttention, subscribeToolAttention } from "@buoy-gg/shared-ui";
|
|
6
6
|
import { useMinimizedTools } from "./MinimizedToolsContext.js";
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* A hidden tool's "I need you". See `setToolAttention` in shared-ui — the tool
|
|
10
|
+
* publishes, the rail draws. Read through useSyncExternalStore so a badge set
|
|
11
|
+
* from inside a minimized sheet lands on the chip without the rail polling.
|
|
12
|
+
*/
|
|
13
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
|
+
function useToolAttention(toolId) {
|
|
15
|
+
return useSyncExternalStore(subscribeToolAttention, () => getToolAttention(toolId), () => getToolAttention(toolId));
|
|
16
|
+
}
|
|
17
|
+
const ATTENTION_COLORS = {
|
|
18
|
+
needsInput: "#FF8329",
|
|
19
|
+
done: "#20C997",
|
|
20
|
+
failed: "#FF3B30"
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/** needsInput outranks failed outranks done — the peek shows the one that matters most. */
|
|
24
|
+
const ATTENTION_RANK = {
|
|
25
|
+
needsInput: 3,
|
|
26
|
+
failed: 2,
|
|
27
|
+
done: 1
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/** The strongest attention across every minimized tool, for the folded peek. */
|
|
31
|
+
function useStrongestAttention(toolIds) {
|
|
32
|
+
const key = toolIds.join("|");
|
|
33
|
+
return useSyncExternalStore(subscribeToolAttention, () => strongest(key), () => strongest(key));
|
|
34
|
+
}
|
|
35
|
+
const strongestCache = new Map();
|
|
36
|
+
function strongest(key) {
|
|
37
|
+
let best = null;
|
|
38
|
+
for (const id of key ? key.split("|") : []) {
|
|
39
|
+
const a = getToolAttention(id);
|
|
40
|
+
if (a && (!best || ATTENTION_RANK[a.kind] > ATTENTION_RANK[best.kind])) best = a;
|
|
41
|
+
}
|
|
42
|
+
// Same value → same object, or useSyncExternalStore re-renders forever.
|
|
43
|
+
const prev = strongestCache.get(key);
|
|
44
|
+
if (prev && best && prev.kind === best.kind && prev.label === best.label) return prev;
|
|
45
|
+
if (!prev && !best) return null;
|
|
46
|
+
strongestCache.set(key, best);
|
|
47
|
+
return best;
|
|
48
|
+
}
|
|
49
|
+
|
|
8
50
|
// ============================================================================
|
|
9
51
|
// Constants
|
|
10
52
|
// ============================================================================
|
|
11
|
-
|
|
53
|
+
|
|
12
54
|
const PEEK_HEIGHT = 28;
|
|
13
55
|
const TOOLBAR_WIDTH = 44;
|
|
14
56
|
const TOOL_ITEM_SIZE = 32;
|
|
@@ -31,6 +73,7 @@ function GlitchToolButton({
|
|
|
31
73
|
onSelect,
|
|
32
74
|
index
|
|
33
75
|
}) {
|
|
76
|
+
const attention = useToolAttention(tool.id);
|
|
34
77
|
const glitchX = useRef(new Animated.Value(0)).current;
|
|
35
78
|
const glitchOpacity = useRef(new Animated.Value(1)).current;
|
|
36
79
|
const glitchScale = useRef(new Animated.Value(1)).current;
|
|
@@ -122,14 +165,14 @@ function GlitchToolButton({
|
|
|
122
165
|
clearTimeout(timeoutId);
|
|
123
166
|
};
|
|
124
167
|
}, [glitchX, glitchOpacity, glitchScale, index]);
|
|
125
|
-
return /*#__PURE__*/
|
|
168
|
+
return /*#__PURE__*/_jsxs(TouchableOpacity, {
|
|
126
169
|
onPress: () => onSelect(tool),
|
|
127
170
|
activeOpacity: 0.7,
|
|
128
171
|
style: styles.toolButton,
|
|
129
|
-
accessibilityLabel: `Restore ${tool.title}`,
|
|
172
|
+
accessibilityLabel: attention ? `${tool.title} — ${attention.label}. Restore` : `Restore ${tool.title}`,
|
|
130
173
|
accessibilityRole: "button",
|
|
131
174
|
testID: `buoy-dock-restore-${tool.id}`,
|
|
132
|
-
children: /*#__PURE__*/_jsx(Animated.View, {
|
|
175
|
+
children: [/*#__PURE__*/_jsx(Animated.View, {
|
|
133
176
|
style: {
|
|
134
177
|
opacity: glitchOpacity,
|
|
135
178
|
transform: [{
|
|
@@ -139,7 +182,17 @@ function GlitchToolButton({
|
|
|
139
182
|
}]
|
|
140
183
|
},
|
|
141
184
|
children: tool.icon
|
|
142
|
-
})
|
|
185
|
+
}), attention ? /*#__PURE__*/_jsx(View, {
|
|
186
|
+
style: [styles.badge, {
|
|
187
|
+
backgroundColor: ATTENTION_COLORS[attention.kind]
|
|
188
|
+
}],
|
|
189
|
+
testID: `buoy-dock-badge-${tool.id}-${attention.kind}`,
|
|
190
|
+
pointerEvents: "none",
|
|
191
|
+
children: attention.kind === "needsInput" ? /*#__PURE__*/_jsx(Text, {
|
|
192
|
+
style: styles.badgeText,
|
|
193
|
+
children: "!"
|
|
194
|
+
}) : null
|
|
195
|
+
}) : null]
|
|
143
196
|
});
|
|
144
197
|
}
|
|
145
198
|
|
|
@@ -159,6 +212,7 @@ export function MinimizedToolsStack({
|
|
|
159
212
|
minimizedTools,
|
|
160
213
|
restore
|
|
161
214
|
} = useMinimizedTools();
|
|
215
|
+
const peekAttention = useStrongestAttention(minimizedTools.map(t => t.id));
|
|
162
216
|
|
|
163
217
|
// Calculate expanded height based on number of tools
|
|
164
218
|
const expandedHeight = TOOLBAR_PADDING + minimizedTools.length * TOOL_ITEM_SIZE + (minimizedTools.length - 1) * ICON_GAP + ICON_GAP + COLLAPSE_BUTTON_SIZE + 4;
|
|
@@ -182,6 +236,11 @@ export function MinimizedToolsStack({
|
|
|
182
236
|
collapsedLabel: `Show ${minimizedTools.length} minimized tools`,
|
|
183
237
|
testID: "buoy-dock-peek",
|
|
184
238
|
collapseTestID: "buoy-dock-collapse",
|
|
239
|
+
attention: peekAttention ? {
|
|
240
|
+
color: ATTENTION_COLORS[peekAttention.kind],
|
|
241
|
+
glyph: peekAttention.kind === "needsInput" ? "!" : undefined,
|
|
242
|
+
label: peekAttention.label
|
|
243
|
+
} : null,
|
|
185
244
|
children: [...minimizedTools].reverse().map((tool, index) => /*#__PURE__*/_jsx(GlitchToolButton, {
|
|
186
245
|
tool: tool,
|
|
187
246
|
onSelect: handleToolPress,
|
|
@@ -201,5 +260,26 @@ const styles = StyleSheet.create({
|
|
|
201
260
|
alignItems: "center",
|
|
202
261
|
justifyContent: "center",
|
|
203
262
|
backgroundColor: "transparent"
|
|
263
|
+
},
|
|
264
|
+
// Top-right of the chip. Needs-input carries a glyph; done/failed are a dot —
|
|
265
|
+
// the colour says which, the glyph says "act".
|
|
266
|
+
badge: {
|
|
267
|
+
position: "absolute",
|
|
268
|
+
top: 0,
|
|
269
|
+
right: 0,
|
|
270
|
+
minWidth: 12,
|
|
271
|
+
height: 12,
|
|
272
|
+
borderRadius: 6,
|
|
273
|
+
paddingHorizontal: 2,
|
|
274
|
+
alignItems: "center",
|
|
275
|
+
justifyContent: "center",
|
|
276
|
+
borderWidth: 1.5,
|
|
277
|
+
borderColor: "#0C0C0C"
|
|
278
|
+
},
|
|
279
|
+
badgeText: {
|
|
280
|
+
color: "#000",
|
|
281
|
+
fontSize: 8,
|
|
282
|
+
fontWeight: "800",
|
|
283
|
+
lineHeight: 9
|
|
204
284
|
}
|
|
205
285
|
});
|
|
@@ -16,8 +16,41 @@
|
|
|
16
16
|
* used before this replaced it.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
20
|
-
import { persistentStorage } from '@buoy-gg/shared-ui';
|
|
19
|
+
import { useCallback, useEffect, useRef, useState, useSyncExternalStore } from 'react';
|
|
20
|
+
import { persistentStorage, getToolAttention, subscribeToolAttention } from '@buoy-gg/shared-ui';
|
|
21
|
+
|
|
22
|
+
/** Twin of the native hook — see MinimizedToolsStack.tsx. */
|
|
23
|
+
function useToolAttention(toolId) {
|
|
24
|
+
return useSyncExternalStore(subscribeToolAttention, () => getToolAttention(toolId), () => getToolAttention(toolId));
|
|
25
|
+
}
|
|
26
|
+
const ATTENTION_COLORS = {
|
|
27
|
+
needsInput: '#FF8329',
|
|
28
|
+
done: '#20C997',
|
|
29
|
+
failed: '#FF3B30'
|
|
30
|
+
};
|
|
31
|
+
const ATTENTION_RANK = {
|
|
32
|
+
needsInput: 3,
|
|
33
|
+
failed: 2,
|
|
34
|
+
done: 1
|
|
35
|
+
};
|
|
36
|
+
const strongestCache = new Map();
|
|
37
|
+
function strongest(key) {
|
|
38
|
+
let best = null;
|
|
39
|
+
for (const id of key ? key.split('|') : []) {
|
|
40
|
+
const a = getToolAttention(id);
|
|
41
|
+
if (a && (!best || ATTENTION_RANK[a.kind] > ATTENTION_RANK[best.kind])) best = a;
|
|
42
|
+
}
|
|
43
|
+
const prev = strongestCache.get(key);
|
|
44
|
+
if (prev && best && prev.kind === best.kind && prev.label === best.label) return prev;
|
|
45
|
+
if (!prev && !best) return null;
|
|
46
|
+
strongestCache.set(key, best);
|
|
47
|
+
return best;
|
|
48
|
+
}
|
|
49
|
+
/** Twin of the native hook: the strongest attention across the folded dock. */
|
|
50
|
+
function useStrongestAttention(toolIds) {
|
|
51
|
+
const key = toolIds.join('|');
|
|
52
|
+
return useSyncExternalStore(subscribeToolAttention, () => strongest(key), () => strongest(key));
|
|
53
|
+
}
|
|
21
54
|
import { useAppHost } from "./AppHost.web.js";
|
|
22
55
|
|
|
23
56
|
// native MinimizedToolsStack.tsx constants
|
|
@@ -58,11 +91,13 @@ function ChevronGlyph({
|
|
|
58
91
|
});
|
|
59
92
|
}
|
|
60
93
|
function GlitchToolButton({
|
|
94
|
+
id,
|
|
61
95
|
title,
|
|
62
96
|
icon,
|
|
63
97
|
index,
|
|
64
98
|
onPress
|
|
65
99
|
}) {
|
|
100
|
+
const attention = useToolAttention(id);
|
|
66
101
|
const innerRef = useRef(null);
|
|
67
102
|
useEffect(() => {
|
|
68
103
|
let mounted = true;
|
|
@@ -113,9 +148,9 @@ function GlitchToolButton({
|
|
|
113
148
|
clearTimeout(timer);
|
|
114
149
|
};
|
|
115
150
|
}, [index]);
|
|
116
|
-
return /*#__PURE__*/
|
|
151
|
+
return /*#__PURE__*/_jsxs("button", {
|
|
117
152
|
type: "button",
|
|
118
|
-
"aria-label": `Restore ${title}`,
|
|
153
|
+
"aria-label": attention ? `${title} — ${attention.label}. Restore` : `Restore ${title}`,
|
|
119
154
|
onClick: onPress,
|
|
120
155
|
style: {
|
|
121
156
|
width: TOOL_ITEM_SIZE,
|
|
@@ -126,9 +161,10 @@ function GlitchToolButton({
|
|
|
126
161
|
background: 'none',
|
|
127
162
|
border: 'none',
|
|
128
163
|
padding: 0,
|
|
129
|
-
cursor: 'pointer'
|
|
164
|
+
cursor: 'pointer',
|
|
165
|
+
position: 'relative'
|
|
130
166
|
},
|
|
131
|
-
children: /*#__PURE__*/_jsx("div", {
|
|
167
|
+
children: [/*#__PURE__*/_jsx("div", {
|
|
132
168
|
ref: innerRef,
|
|
133
169
|
style: {
|
|
134
170
|
display: 'flex',
|
|
@@ -136,7 +172,30 @@ function GlitchToolButton({
|
|
|
136
172
|
justifyContent: 'center'
|
|
137
173
|
},
|
|
138
174
|
children: icon
|
|
139
|
-
})
|
|
175
|
+
}), attention ? /*#__PURE__*/_jsx("span", {
|
|
176
|
+
"aria-hidden": true,
|
|
177
|
+
"data-testid": `buoy-dock-badge-${id}-${attention.kind}`,
|
|
178
|
+
style: {
|
|
179
|
+
position: 'absolute',
|
|
180
|
+
top: 0,
|
|
181
|
+
right: 0,
|
|
182
|
+
minWidth: 12,
|
|
183
|
+
height: 12,
|
|
184
|
+
borderRadius: 6,
|
|
185
|
+
padding: '0 2px',
|
|
186
|
+
boxSizing: 'border-box',
|
|
187
|
+
background: ATTENTION_COLORS[attention.kind],
|
|
188
|
+
border: '1.5px solid #0C0C0C',
|
|
189
|
+
color: '#000',
|
|
190
|
+
fontSize: 8,
|
|
191
|
+
fontWeight: 800,
|
|
192
|
+
lineHeight: '9px',
|
|
193
|
+
display: 'flex',
|
|
194
|
+
alignItems: 'center',
|
|
195
|
+
justifyContent: 'center'
|
|
196
|
+
},
|
|
197
|
+
children: attention.kind === 'needsInput' ? '!' : ''
|
|
198
|
+
}) : null]
|
|
140
199
|
});
|
|
141
200
|
}
|
|
142
201
|
export function MinimizedToolsStack({
|
|
@@ -149,6 +208,7 @@ export function MinimizedToolsStack({
|
|
|
149
208
|
const minimized = openApps.filter(app => app.minimized && app.launchMode !== 'toggle-only');
|
|
150
209
|
const [isExpanded, setIsExpanded] = useState(false);
|
|
151
210
|
const [isStateRestored, setIsStateRestored] = useState(false);
|
|
211
|
+
const peekAttention = useStrongestAttention(minimized.map(app => app.id));
|
|
152
212
|
|
|
153
213
|
// Restore + persist the expanded flag (native ExpandablePopover persistState).
|
|
154
214
|
useEffect(() => {
|
|
@@ -216,6 +276,7 @@ export function MinimizedToolsStack({
|
|
|
216
276
|
boxSizing: 'border-box'
|
|
217
277
|
},
|
|
218
278
|
children: [[...minimized].reverse().map((app, index) => /*#__PURE__*/_jsx(GlitchToolButton, {
|
|
279
|
+
id: app.id,
|
|
219
280
|
title: app.title || app.id,
|
|
220
281
|
icon: app.icon ?? /*#__PURE__*/_jsx("span", {
|
|
221
282
|
style: {
|
|
@@ -270,7 +331,30 @@ export function MinimizedToolsStack({
|
|
|
270
331
|
pointerEvents: isExpanded ? 'none' : 'auto',
|
|
271
332
|
...frame
|
|
272
333
|
},
|
|
273
|
-
children: [/*#__PURE__*/_jsx(ChevronGlyph, {}),
|
|
334
|
+
children: [/*#__PURE__*/_jsx(ChevronGlyph, {}), peekAttention ? /*#__PURE__*/_jsx("span", {
|
|
335
|
+
"aria-hidden": true,
|
|
336
|
+
"data-testid": `buoy-dock-peek-attention`,
|
|
337
|
+
style: {
|
|
338
|
+
position: 'absolute',
|
|
339
|
+
top: 2,
|
|
340
|
+
right: 2,
|
|
341
|
+
minWidth: 11,
|
|
342
|
+
height: 11,
|
|
343
|
+
borderRadius: 6,
|
|
344
|
+
padding: '0 2px',
|
|
345
|
+
boxSizing: 'border-box',
|
|
346
|
+
background: ATTENTION_COLORS[peekAttention.kind],
|
|
347
|
+
border: '1.5px solid #0C0C0C',
|
|
348
|
+
color: '#000',
|
|
349
|
+
fontSize: 8,
|
|
350
|
+
fontWeight: 800,
|
|
351
|
+
lineHeight: '9px',
|
|
352
|
+
display: 'flex',
|
|
353
|
+
alignItems: 'center',
|
|
354
|
+
justifyContent: 'center'
|
|
355
|
+
},
|
|
356
|
+
children: peekAttention.kind === 'needsInput' ? '!' : ''
|
|
357
|
+
}) : null, minimized.length > 1 && /*#__PURE__*/_jsx("span", {
|
|
274
358
|
style: {
|
|
275
359
|
fontSize: 9,
|
|
276
360
|
fontWeight: 600,
|
package/lib/module/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MinimizedToolsStack.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/MinimizedToolsStack.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"MinimizedToolsStack.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/MinimizedToolsStack.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+D,MAAM,OAAO,CAAC;AAepF,OAAO,EAAqB,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAsP3E,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,qBA0D1B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MinimizedToolsStack.web.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/MinimizedToolsStack.web.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;
|
|
1
|
+
{"version":3,"file":"MinimizedToolsStack.web.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/MinimizedToolsStack.web.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAiMH,MAAM,WAAW,wBAAwB;IACvC,gEAAgE;IAChE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,mBAAmB,CAAC,EAAE,cAAmB,EAAE,EAAE,wBAAwB,sCAmMpF"}
|
|
@@ -9,5 +9,5 @@
|
|
|
9
9
|
* Drift is prevented by a test that fails when this disagrees with
|
|
10
10
|
* package.json, so a version bump that forgets this file cannot ship.
|
|
11
11
|
*/
|
|
12
|
-
export declare const SDK_VERSION = "7.0.
|
|
12
|
+
export declare const SDK_VERSION = "7.0.36";
|
|
13
13
|
//# sourceMappingURL=version.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MinimizedToolsStack.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/MinimizedToolsStack.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"MinimizedToolsStack.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/MinimizedToolsStack.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+D,MAAM,OAAO,CAAC;AAepF,OAAO,EAAqB,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAsP3E,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,qBA0D1B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MinimizedToolsStack.web.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/MinimizedToolsStack.web.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;
|
|
1
|
+
{"version":3,"file":"MinimizedToolsStack.web.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/MinimizedToolsStack.web.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAiMH,MAAM,WAAW,wBAAwB;IACvC,gEAAgE;IAChE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,mBAAmB,CAAC,EAAE,cAAmB,EAAE,EAAE,wBAAwB,sCAmMpF"}
|
|
@@ -9,5 +9,5 @@
|
|
|
9
9
|
* Drift is prevented by a test that fails when this disagrees with
|
|
10
10
|
* package.json, so a version bump that forgets this file cannot ship.
|
|
11
11
|
*/
|
|
12
|
-
export declare const SDK_VERSION = "7.0.
|
|
12
|
+
export declare const SDK_VERSION = "7.0.36";
|
|
13
13
|
//# sourceMappingURL=version.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@buoy-gg/core",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.36",
|
|
4
4
|
"description": "Buoy devtools for React Native — a floating in-app dev menu; every tool streams live to your phone, desktop, and AI agent.",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
@@ -37,10 +37,10 @@
|
|
|
37
37
|
],
|
|
38
38
|
"sideEffects": false,
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@buoy-gg/shared-ui": "^7.0.
|
|
41
|
-
"@buoy-gg/
|
|
42
|
-
"@buoy-gg/
|
|
43
|
-
"@buoy-gg/floating-tools-
|
|
40
|
+
"@buoy-gg/shared-ui": "^7.0.36",
|
|
41
|
+
"@buoy-gg/license": "^7.0.36",
|
|
42
|
+
"@buoy-gg/floating-tools-react": "^7.0.36",
|
|
43
|
+
"@buoy-gg/floating-tools-core": "^7.0.36"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"react": "*",
|