@buoy-gg/ask-buoy 7.0.33

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 (184) hide show
  1. package/LICENSE +58 -0
  2. package/README.md +50 -0
  3. package/lib/commonjs/blocks/AskBlocks.js +338 -0
  4. package/lib/commonjs/blocks/AskBlocks.js.map +1 -0
  5. package/lib/commonjs/blocks/BlockRenderer.js +250 -0
  6. package/lib/commonjs/blocks/BlockRenderer.js.map +1 -0
  7. package/lib/commonjs/blocks/ChromePrototypes.js +514 -0
  8. package/lib/commonjs/blocks/ChromePrototypes.js.map +1 -0
  9. package/lib/commonjs/blocks/DataBlocks.js +545 -0
  10. package/lib/commonjs/blocks/DataBlocks.js.map +1 -0
  11. package/lib/commonjs/blocks/ExtraBlocks.js +1821 -0
  12. package/lib/commonjs/blocks/ExtraBlocks.js.map +1 -0
  13. package/lib/commonjs/blocks/MediaBlocks.js +140 -0
  14. package/lib/commonjs/blocks/MediaBlocks.js.map +1 -0
  15. package/lib/commonjs/blocks/ReceiptBlocks.js +596 -0
  16. package/lib/commonjs/blocks/ReceiptBlocks.js.map +1 -0
  17. package/lib/commonjs/blocks/context.js +42 -0
  18. package/lib/commonjs/blocks/context.js.map +1 -0
  19. package/lib/commonjs/blocks/icons.js +96 -0
  20. package/lib/commonjs/blocks/icons.js.map +1 -0
  21. package/lib/commonjs/blocks/index.js +95 -0
  22. package/lib/commonjs/blocks/index.js.map +1 -0
  23. package/lib/commonjs/blocks/primitives.js +312 -0
  24. package/lib/commonjs/blocks/primitives.js.map +1 -0
  25. package/lib/commonjs/blocks/primitivesIndex.js +56 -0
  26. package/lib/commonjs/blocks/primitivesIndex.js.map +1 -0
  27. package/lib/commonjs/components/ApprovalCard.js +140 -0
  28. package/lib/commonjs/components/ApprovalCard.js.map +1 -0
  29. package/lib/commonjs/components/AskBuoyHeader.js +127 -0
  30. package/lib/commonjs/components/AskBuoyHeader.js.map +1 -0
  31. package/lib/commonjs/components/AskBuoyIcon.js +19 -0
  32. package/lib/commonjs/components/AskBuoyIcon.js.map +1 -0
  33. package/lib/commonjs/components/AskBuoyModal.js +322 -0
  34. package/lib/commonjs/components/AskBuoyModal.js.map +1 -0
  35. package/lib/commonjs/components/ChangesBar.js +211 -0
  36. package/lib/commonjs/components/ChangesBar.js.map +1 -0
  37. package/lib/commonjs/components/Composer.js +175 -0
  38. package/lib/commonjs/components/Composer.js.map +1 -0
  39. package/lib/commonjs/components/EmptyState.js +154 -0
  40. package/lib/commonjs/components/EmptyState.js.map +1 -0
  41. package/lib/commonjs/components/Markdown.js +252 -0
  42. package/lib/commonjs/components/Markdown.js.map +1 -0
  43. package/lib/commonjs/components/MessageList.js +648 -0
  44. package/lib/commonjs/components/MessageList.js.map +1 -0
  45. package/lib/commonjs/components/TypingDots.js +63 -0
  46. package/lib/commonjs/components/TypingDots.js.map +1 -0
  47. package/lib/commonjs/index.js +205 -0
  48. package/lib/commonjs/index.js.map +1 -0
  49. package/lib/commonjs/package.json +1 -0
  50. package/lib/commonjs/preset.js +90 -0
  51. package/lib/commonjs/preset.js.map +1 -0
  52. package/lib/commonjs/store/askBuoyStore.js +279 -0
  53. package/lib/commonjs/store/askBuoyStore.js.map +1 -0
  54. package/lib/commonjs/store/useAskBuoy.js +299 -0
  55. package/lib/commonjs/store/useAskBuoy.js.map +1 -0
  56. package/lib/commonjs/sync/askBuoySyncAdapter.js +119 -0
  57. package/lib/commonjs/sync/askBuoySyncAdapter.js.map +1 -0
  58. package/lib/commonjs/sync/askBuoySyncAdapter.test.js +136 -0
  59. package/lib/commonjs/sync/askBuoySyncAdapter.test.js.map +1 -0
  60. package/lib/commonjs/sync/wire.js +58 -0
  61. package/lib/commonjs/sync/wire.js.map +1 -0
  62. package/lib/commonjs/types.js +6 -0
  63. package/lib/commonjs/types.js.map +1 -0
  64. package/lib/module/blocks/AskBlocks.js +331 -0
  65. package/lib/module/blocks/AskBlocks.js.map +1 -0
  66. package/lib/module/blocks/BlockRenderer.js +245 -0
  67. package/lib/module/blocks/BlockRenderer.js.map +1 -0
  68. package/lib/module/blocks/ChromePrototypes.js +503 -0
  69. package/lib/module/blocks/ChromePrototypes.js.map +1 -0
  70. package/lib/module/blocks/DataBlocks.js +532 -0
  71. package/lib/module/blocks/DataBlocks.js.map +1 -0
  72. package/lib/module/blocks/ExtraBlocks.js +1794 -0
  73. package/lib/module/blocks/ExtraBlocks.js.map +1 -0
  74. package/lib/module/blocks/MediaBlocks.js +135 -0
  75. package/lib/module/blocks/MediaBlocks.js.map +1 -0
  76. package/lib/module/blocks/ReceiptBlocks.js +584 -0
  77. package/lib/module/blocks/ReceiptBlocks.js.map +1 -0
  78. package/lib/module/blocks/context.js +35 -0
  79. package/lib/module/blocks/context.js.map +1 -0
  80. package/lib/module/blocks/icons.js +91 -0
  81. package/lib/module/blocks/icons.js.map +1 -0
  82. package/lib/module/blocks/index.js +8 -0
  83. package/lib/module/blocks/index.js.map +1 -0
  84. package/lib/module/blocks/primitives.js +301 -0
  85. package/lib/module/blocks/primitives.js.map +1 -0
  86. package/lib/module/blocks/primitivesIndex.js +5 -0
  87. package/lib/module/blocks/primitivesIndex.js.map +1 -0
  88. package/lib/module/components/ApprovalCard.js +135 -0
  89. package/lib/module/components/ApprovalCard.js.map +1 -0
  90. package/lib/module/components/AskBuoyHeader.js +124 -0
  91. package/lib/module/components/AskBuoyHeader.js.map +1 -0
  92. package/lib/module/components/AskBuoyIcon.js +8 -0
  93. package/lib/module/components/AskBuoyIcon.js.map +1 -0
  94. package/lib/module/components/AskBuoyModal.js +317 -0
  95. package/lib/module/components/AskBuoyModal.js.map +1 -0
  96. package/lib/module/components/ChangesBar.js +206 -0
  97. package/lib/module/components/ChangesBar.js.map +1 -0
  98. package/lib/module/components/Composer.js +170 -0
  99. package/lib/module/components/Composer.js.map +1 -0
  100. package/lib/module/components/EmptyState.js +149 -0
  101. package/lib/module/components/EmptyState.js.map +1 -0
  102. package/lib/module/components/Markdown.js +246 -0
  103. package/lib/module/components/Markdown.js.map +1 -0
  104. package/lib/module/components/MessageList.js +642 -0
  105. package/lib/module/components/MessageList.js.map +1 -0
  106. package/lib/module/components/TypingDots.js +58 -0
  107. package/lib/module/components/TypingDots.js.map +1 -0
  108. package/lib/module/index.js +29 -0
  109. package/lib/module/index.js.map +1 -0
  110. package/lib/module/preset.js +73 -0
  111. package/lib/module/preset.js.map +1 -0
  112. package/lib/module/store/askBuoyStore.js +275 -0
  113. package/lib/module/store/askBuoyStore.js.map +1 -0
  114. package/lib/module/store/useAskBuoy.js +293 -0
  115. package/lib/module/store/useAskBuoy.js.map +1 -0
  116. package/lib/module/sync/askBuoySyncAdapter.js +114 -0
  117. package/lib/module/sync/askBuoySyncAdapter.js.map +1 -0
  118. package/lib/module/sync/askBuoySyncAdapter.test.js +135 -0
  119. package/lib/module/sync/askBuoySyncAdapter.test.js.map +1 -0
  120. package/lib/module/sync/wire.js +47 -0
  121. package/lib/module/sync/wire.js.map +1 -0
  122. package/lib/module/types.js +4 -0
  123. package/lib/module/types.js.map +1 -0
  124. package/lib/typescript/blocks/AskBlocks.d.ts +11 -0
  125. package/lib/typescript/blocks/AskBlocks.d.ts.map +1 -0
  126. package/lib/typescript/blocks/BlockRenderer.d.ts +5 -0
  127. package/lib/typescript/blocks/BlockRenderer.d.ts.map +1 -0
  128. package/lib/typescript/blocks/ChromePrototypes.d.ts +27 -0
  129. package/lib/typescript/blocks/ChromePrototypes.d.ts.map +1 -0
  130. package/lib/typescript/blocks/DataBlocks.d.ts +29 -0
  131. package/lib/typescript/blocks/DataBlocks.d.ts.map +1 -0
  132. package/lib/typescript/blocks/ExtraBlocks.d.ts +69 -0
  133. package/lib/typescript/blocks/ExtraBlocks.d.ts.map +1 -0
  134. package/lib/typescript/blocks/MediaBlocks.d.ts +5 -0
  135. package/lib/typescript/blocks/MediaBlocks.d.ts.map +1 -0
  136. package/lib/typescript/blocks/ReceiptBlocks.d.ts +27 -0
  137. package/lib/typescript/blocks/ReceiptBlocks.d.ts.map +1 -0
  138. package/lib/typescript/blocks/context.d.ts +35 -0
  139. package/lib/typescript/blocks/context.d.ts.map +1 -0
  140. package/lib/typescript/blocks/icons.d.ts +6 -0
  141. package/lib/typescript/blocks/icons.d.ts.map +1 -0
  142. package/lib/typescript/blocks/index.d.ts +6 -0
  143. package/lib/typescript/blocks/index.d.ts.map +1 -0
  144. package/lib/typescript/blocks/primitives.d.ts +85 -0
  145. package/lib/typescript/blocks/primitives.d.ts.map +1 -0
  146. package/lib/typescript/blocks/primitivesIndex.d.ts +3 -0
  147. package/lib/typescript/blocks/primitivesIndex.d.ts.map +1 -0
  148. package/lib/typescript/components/ApprovalCard.d.ts +7 -0
  149. package/lib/typescript/components/ApprovalCard.d.ts.map +1 -0
  150. package/lib/typescript/components/AskBuoyHeader.d.ts +14 -0
  151. package/lib/typescript/components/AskBuoyHeader.d.ts.map +1 -0
  152. package/lib/typescript/components/AskBuoyIcon.d.ts +6 -0
  153. package/lib/typescript/components/AskBuoyIcon.d.ts.map +1 -0
  154. package/lib/typescript/components/AskBuoyModal.d.ts +13 -0
  155. package/lib/typescript/components/AskBuoyModal.d.ts.map +1 -0
  156. package/lib/typescript/components/ChangesBar.d.ts +9 -0
  157. package/lib/typescript/components/ChangesBar.d.ts.map +1 -0
  158. package/lib/typescript/components/Composer.d.ts +9 -0
  159. package/lib/typescript/components/Composer.d.ts.map +1 -0
  160. package/lib/typescript/components/EmptyState.d.ts +6 -0
  161. package/lib/typescript/components/EmptyState.d.ts.map +1 -0
  162. package/lib/typescript/components/Markdown.d.ts +23 -0
  163. package/lib/typescript/components/Markdown.d.ts.map +1 -0
  164. package/lib/typescript/components/MessageList.d.ts +18 -0
  165. package/lib/typescript/components/MessageList.d.ts.map +1 -0
  166. package/lib/typescript/components/TypingDots.d.ts +2 -0
  167. package/lib/typescript/components/TypingDots.d.ts.map +1 -0
  168. package/lib/typescript/index.d.ts +28 -0
  169. package/lib/typescript/index.d.ts.map +1 -0
  170. package/lib/typescript/preset.d.ts +61 -0
  171. package/lib/typescript/preset.d.ts.map +1 -0
  172. package/lib/typescript/store/askBuoyStore.d.ts +124 -0
  173. package/lib/typescript/store/askBuoyStore.d.ts.map +1 -0
  174. package/lib/typescript/store/useAskBuoy.d.ts +22 -0
  175. package/lib/typescript/store/useAskBuoy.d.ts.map +1 -0
  176. package/lib/typescript/sync/askBuoySyncAdapter.d.ts +73 -0
  177. package/lib/typescript/sync/askBuoySyncAdapter.d.ts.map +1 -0
  178. package/lib/typescript/sync/askBuoySyncAdapter.test.d.ts +2 -0
  179. package/lib/typescript/sync/askBuoySyncAdapter.test.d.ts.map +1 -0
  180. package/lib/typescript/sync/wire.d.ts +17 -0
  181. package/lib/typescript/sync/wire.d.ts.map +1 -0
  182. package/lib/typescript/types.d.ts +119 -0
  183. package/lib/typescript/types.d.ts.map +1 -0
  184. package/package.json +83 -0
@@ -0,0 +1,293 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Wire the sheet to the agent.
5
+ *
6
+ * Two things here are load-bearing:
7
+ *
8
+ * 1. DISPATCH GOES THROUGH `dispatchToolAction`, the same on-device seam a
9
+ * Scenario step and a desktop click use. No second adapter map, nothing
10
+ * that can drift from what the broker sees.
11
+ * 2. THE SESSION IS REBUILT WHEN THE TOOL LIST CHANGES. The adapter map is a
12
+ * memo whose contents depend on which packages resolved and whether a
13
+ * QueryClientProvider is above FloatingDevTools — it is per-app and per
14
+ * render, never a constant. A session that cached the tool list at open
15
+ * would offer the model tools that are no longer there.
16
+ */
17
+ import { useCallback, useEffect, useMemo, useRef, useSyncExternalStore } from "react";
18
+ import { Platform } from "react-native";
19
+ import { dispatchToolAction, listSnapshotToolIds, listToolActions, readToolSnapshot, waitForToolRegistry } from "@buoy-gg/shared-ui";
20
+ import { answerToText, CATALOG, createAskBuoySession, runGatedAction, SNAPSHOT_ACTION } from "@buoy-gg/agent-core";
21
+ import { askBuoyStore } from "./askBuoyStore";
22
+ const isRelease = typeof __DEV__ !== "undefined" && !__DEV__;
23
+ export function useAskBuoyState() {
24
+ return useSyncExternalStore(askBuoyStore.subscribe, askBuoyStore.getState, askBuoyStore.getState);
25
+ }
26
+ export function useAskBuoy(config) {
27
+ const state = useAskBuoyState();
28
+ const sessionRef = useRef(null);
29
+ const abortRef = useRef(null);
30
+ // Read through a ref where a stable callback needs the LATEST config (the
31
+ // onEvent tap) without re-creating the callback per render.
32
+ const configRef = useRef(config);
33
+ configRef.current = config;
34
+ const configured = !!config?.endpoint && !!config?.model;
35
+
36
+ // Recomputed each render: the set of dispatchable tools is not a constant.
37
+ //
38
+ // `getSnapshot` is folded in here because half of Buoy's read surface is not
39
+ // an action at all — console entries, network events, routes and env live
40
+ // only in the adapter's snapshot. Without this the model is offered a
41
+ // console tool whose sole action wipes the logs, and no way to read them.
42
+ const availableActions = useMemo(() => {
43
+ try {
44
+ const actions = listToolActions();
45
+ for (const toolId of listSnapshotToolIds()) {
46
+ if (!actions[toolId]) actions[toolId] = [];
47
+ if (!actions[toolId].includes(SNAPSHOT_ACTION)) {
48
+ actions[toolId] = [SNAPSHOT_ACTION, ...actions[toolId]];
49
+ }
50
+ }
51
+ return actions;
52
+ } catch {
53
+ return {};
54
+ }
55
+ }, []);
56
+ const toolKey = Object.keys(availableActions).sort().join(",");
57
+ useEffect(() => {
58
+ askBuoyStore.setConfigured(configured);
59
+ if (!configured || !config) {
60
+ sessionRef.current = null;
61
+ askBuoyStore.setNotice("Ask Buoy isn't set up in this app yet. A developer needs to point it at your team's AI endpoint.");
62
+ return;
63
+ }
64
+ // The classic first-run mistake, caught statically: a provider's own URL
65
+ // with the wrong protocol fails with a raw error that says nothing about
66
+ // the one-line fix. ONLY the canonical provider hosts are checked — a
67
+ // gateway may legitimately speak either protocol on any path (our own dev
68
+ // gateway serves OpenAI framing on /v1/messages, and a path-based version
69
+ // of this check flagged it on the first device run).
70
+ const protocol = config.protocol ?? "anthropic";
71
+ if (isRelease && config.apiKey) {
72
+ askBuoyStore.setNotice("This build carries a plaintext apiKey — that's dev-only and it ships to every install. Use the headers callback with your own gateway for distributed builds.");
73
+ } else if (protocol === "anthropic" && /^https?:\/\/api\.openai\.com\//i.test(config.endpoint)) {
74
+ askBuoyStore.setNotice('This endpoint is api.openai.com but the protocol is "anthropic". Set protocol: "openai" in the askBuoy config.');
75
+ } else if (protocol === "openai" && /^https?:\/\/api\.anthropic\.com\//i.test(config.endpoint)) {
76
+ askBuoyStore.setNotice('This endpoint is api.anthropic.com but the protocol is "openai". Remove protocol or set it to "anthropic".');
77
+ } else {
78
+ askBuoyStore.setNotice(null);
79
+ }
80
+
81
+ // Reuse the held session while nothing material changed. The transcript
82
+ // already survives close/reopen in the module store; without this the
83
+ // session and ledger did not — reopening the sheet swapped in an empty
84
+ // ledger (undo bar gone, agent changes still live in the app) and a blank
85
+ // model memory behind a transcript that still showed the conversation.
86
+ // The tool list is deliberately NOT part of this signature. Packages
87
+ // register a frame or two apart, so `toolKey` legitimately changes right
88
+ // after open — and keying on it silently rebuilt the session mid-chat,
89
+ // throwing away the conversation, the model's memory and the undo ledger
90
+ // while the transcript (a separate store) kept rendering as if nothing
91
+ // happened. Verified on device: a destructive change went unrecorded
92
+ // because it landed in a ledger that had just been replaced.
93
+ const signature = [config.endpoint, config.protocol ?? "anthropic", config.model].join("|");
94
+ const held = askBuoyStore.getHeldSession();
95
+ if (held && held.signature === signature) {
96
+ sessionRef.current = held.session;
97
+ held.session.setAvailableActions(availableActions);
98
+ askBuoyStore.setLedger(held.session.ledger);
99
+ return;
100
+ }
101
+ const session = createAskBuoySession({
102
+ endpoint: config.endpoint,
103
+ protocol: config.protocol ?? "anthropic",
104
+ model: config.model,
105
+ headers: config.headers,
106
+ apiKey: config.apiKey,
107
+ maxTokens: config.maxTokens,
108
+ anthropicVersion: config.anthropicVersion,
109
+ requestOverrides: config.requestOverrides,
110
+ // Host-declared custom tools join the built-in catalog. toProviderTools
111
+ // still filters against the live registry, so a descriptor whose
112
+ // `custom:<id>` adapter never registered is simply not offered.
113
+ catalog: config.tools?.length ? [...CATALOG, ...config.tools] : undefined,
114
+ dispatch: dispatchToolAction,
115
+ readSnapshot: readToolSnapshot,
116
+ availableActions,
117
+ policy: config.policy,
118
+ context: config.context,
119
+ isRelease,
120
+ appName: config.appName,
121
+ platform: Platform.OS,
122
+ requestApproval: input => askBuoyStore.askApproval(input)
123
+ });
124
+ sessionRef.current = session;
125
+ askBuoyStore.holdSession(session, signature);
126
+ askBuoyStore.setLedger(session.ledger);
127
+
128
+ // The registry publishes on mount, a frame or two after first paint. Warm
129
+ // the grounding once it is there so the first question does not pay for it.
130
+ let cancelled = false;
131
+ void waitForToolRegistry().then(ready => {
132
+ if (ready && !cancelled) void session.prime();
133
+ });
134
+ return () => {
135
+ cancelled = true;
136
+ };
137
+ }, [configured, config, availableActions, toolKey]);
138
+
139
+ /** Stream one turn into a fresh assistant bubble. Callers set up the user side. */
140
+ const runTurn = useCallback(text => {
141
+ const session = sessionRef.current;
142
+ if (!session) return;
143
+ askBuoyStore.beginTurn();
144
+ const messageId = askBuoyStore.startAssistant();
145
+ const controller = new AbortController();
146
+ abortRef.current = controller;
147
+ const onEvent = configRef.current?.onEvent;
148
+ void (async () => {
149
+ try {
150
+ for await (const ev of session.send(text, controller.signal)) {
151
+ askBuoyStore.applyEvent(messageId, ev);
152
+ if (onEvent) {
153
+ try {
154
+ onEvent(ev);
155
+ } catch {
156
+ // The audit tap must never take the chat down.
157
+ }
158
+ }
159
+ }
160
+ } catch (err) {
161
+ askBuoyStore.applyEvent(messageId, {
162
+ type: "error",
163
+ message: err instanceof Error ? err.message : "Something went wrong talking to your AI endpoint."
164
+ });
165
+ } finally {
166
+ askBuoyStore.finishAssistant(messageId);
167
+ abortRef.current = null;
168
+ }
169
+ })();
170
+ }, []);
171
+ const send = useCallback(text => {
172
+ const trimmed = text.trim();
173
+ if (!sessionRef.current || !trimmed) return;
174
+
175
+ // Typed mid-turn: park it. The composer already cleared the field, and
176
+ // silently dropping the words was the worst of all outcomes.
177
+ if (askBuoyStore.getState().busy) {
178
+ askBuoyStore.setQueued(trimmed);
179
+ return;
180
+ }
181
+
182
+ // Typing past an Ask block IS an answer: the block is skipped and locks.
183
+ // Without this the composer stayed on "Pick an option above…" forever and
184
+ // a stale choice sat tappable in the history.
185
+ const awaiting = askBuoyStore.getState().awaitingBlockId;
186
+ if (awaiting) askBuoyStore.recordAnswer({
187
+ blockId: awaiting,
188
+ kind: "skipped"
189
+ });
190
+ askBuoyStore.addUser(trimmed);
191
+ runTurn(trimmed);
192
+ }, [runTurn]);
193
+ const retry = useCallback(() => {
194
+ const {
195
+ messages,
196
+ busy
197
+ } = askBuoyStore.getState();
198
+ if (busy || !sessionRef.current) return;
199
+ const lastUser = [...messages].reverse().find(m => m.role === "user");
200
+ if (!lastUser) return;
201
+ // Replace the failed bubble rather than stacking a second one under it.
202
+ const last = messages[messages.length - 1];
203
+ if (last && last.role === "assistant" && last.error) askBuoyStore.removeMessage(last.id);
204
+ runTurn(lastUser.text);
205
+ }, [runTurn]);
206
+ const stop = useCallback(() => {
207
+ // A pending approval parks an unresolved promise inside the engine; the
208
+ // abort signal is only read between steps, so Stop must also answer the
209
+ // approval (as declined) or the generator hangs forever.
210
+ if (askBuoyStore.getState().pending) askBuoyStore.answerApproval(false);
211
+ abortRef.current?.abort();
212
+ abortRef.current = null;
213
+ }, []);
214
+
215
+ // Flush the parked message the moment the turn ends.
216
+ const queued = state.queued;
217
+ useEffect(() => {
218
+ if (!state.busy && queued) {
219
+ askBuoyStore.setQueued(null);
220
+ send(queued);
221
+ }
222
+ }, [state.busy, queued, send]);
223
+ const reset = useCallback(() => {
224
+ abortRef.current?.abort();
225
+ sessionRef.current?.reset();
226
+ askBuoyStore.reset();
227
+ }, []);
228
+ const approve = useCallback(approved => {
229
+ askBuoyStore.answerApproval(approved);
230
+ }, []);
231
+ const answer = useCallback(a => {
232
+ askBuoyStore.recordAnswer(a);
233
+ // Plain words to the model, never JSON: "Business checkout", "Yes, go ahead."
234
+ send(answerToText(a));
235
+ }, [send]);
236
+
237
+ /**
238
+ * Block buttons. `send` is a chat reply; `dispatch` runs the action through
239
+ * `runGatedAction` — the SAME validation, policy and ledger path a model
240
+ * call takes, minus the model. The first version called `dispatchToolAction`
241
+ * raw, which made a model-authored button an invisible, ungoverned,
242
+ * unundoable mutation while the `buoy_ui` schema promised the opposite.
243
+ * The human's tap satisfies `requireApproval`; deny lists, read-only mode
244
+ * and release refusals still stand. Button state is tracked so a tap shows
245
+ * running → done and can't double-fire.
246
+ * (`minimize` / `openTool` are the sheet's to handle; see AskBuoyModal.)
247
+ */
248
+ const runAction = useCallback(async (action, blockId) => {
249
+ if (action.send) {
250
+ send(action.send);
251
+ return;
252
+ }
253
+ if (!action.dispatch) return;
254
+ const key = `${blockId}:${action.label}`;
255
+ const ledger = askBuoyStore.getLedger();
256
+ if (!ledger) {
257
+ askBuoyStore.setNotice(`${action.label} failed — no active Ask Buoy session.`);
258
+ return;
259
+ }
260
+ askBuoyStore.setActionState(key, "running");
261
+ const outcome = await runGatedAction({
262
+ toolId: action.dispatch.toolId,
263
+ action: action.dispatch.action,
264
+ params: action.dispatch.params ?? {},
265
+ dispatch: dispatchToolAction,
266
+ ledger,
267
+ policy: config?.policy ?? {},
268
+ isRelease,
269
+ // Same merged catalog the session offers, so a button on a custom
270
+ // tool's block is not refused as unknown.
271
+ catalog: config?.tools?.length ? [...CATALOG, ...config.tools] : undefined
272
+ });
273
+ if (outcome.ok) {
274
+ askBuoyStore.setActionState(key, "done");
275
+ } else {
276
+ askBuoyStore.setActionState(key, "failed");
277
+ askBuoyStore.setNotice(`${action.label} failed — ${outcome.error}`);
278
+ }
279
+ }, [send, config]);
280
+ return {
281
+ state,
282
+ send,
283
+ stop,
284
+ reset,
285
+ approve,
286
+ retry,
287
+ answer,
288
+ runAction,
289
+ configured,
290
+ toolCount: Object.keys(availableActions).length
291
+ };
292
+ }
293
+ //# sourceMappingURL=useAskBuoy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useCallback","useEffect","useMemo","useRef","useSyncExternalStore","Platform","dispatchToolAction","listSnapshotToolIds","listToolActions","readToolSnapshot","waitForToolRegistry","answerToText","CATALOG","createAskBuoySession","runGatedAction","SNAPSHOT_ACTION","askBuoyStore","isRelease","__DEV__","useAskBuoyState","subscribe","getState","useAskBuoy","config","state","sessionRef","abortRef","configRef","current","configured","endpoint","model","availableActions","actions","toolId","includes","toolKey","Object","keys","sort","join","setConfigured","setNotice","protocol","apiKey","test","signature","held","getHeldSession","session","setAvailableActions","setLedger","ledger","headers","maxTokens","anthropicVersion","requestOverrides","catalog","tools","length","undefined","dispatch","readSnapshot","policy","context","appName","platform","OS","requestApproval","input","askApproval","holdSession","cancelled","then","ready","prime","runTurn","text","beginTurn","messageId","startAssistant","controller","AbortController","onEvent","ev","send","signal","applyEvent","err","type","message","Error","finishAssistant","trimmed","trim","busy","setQueued","awaiting","awaitingBlockId","recordAnswer","blockId","kind","addUser","retry","messages","lastUser","reverse","find","m","role","last","error","removeMessage","id","stop","pending","answerApproval","abort","queued","reset","approve","approved","answer","a","runAction","action","key","label","getLedger","setActionState","outcome","params","ok","toolCount"],"sourceRoot":"../../../src","sources":["store/useAskBuoy.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * The sync adapter, so Buoy Desktop and MCP can see what Ask Buoy is doing.
5
+ *
6
+ * Read-heavy on purpose. There is no `send` action: letting a remote client
7
+ * put words in the agent's mouth would mean anyone who can reach the broker —
8
+ * which has no authentication at all, binds 0.0.0.0, and accepts any client
9
+ * calling itself "Dashboard" — could drive a mutating agent on a tester's
10
+ * device. The chat is initiated on-device, by a person, full stop.
11
+ *
12
+ * `undoAll` IS exposed, because the asymmetry is deliberate: putting things
13
+ * back is the safe direction, and a dev watching from the desktop should be
14
+ * able to clean up a device without walking over to it.
15
+ *
16
+ * The transcript is redacted before it crosses the wire. Action results the
17
+ * agent read can contain storage values and response bodies, and this socket
18
+ * broadcasts to every connected dashboard — it already leaks license keys the
19
+ * same way.
20
+ */
21
+ import { dispatchToolAction, redactForWire } from "./wire";
22
+ import { isReversible } from "@buoy-gg/agent-core";
23
+ import { askBuoyStore } from "../store/askBuoyStore";
24
+ export const ASK_BUOY_ADAPTER_VERSION = 1;
25
+ export const askBuoySyncAdapter = {
26
+ version: ASK_BUOY_ADAPTER_VERSION,
27
+ getSnapshot() {
28
+ const state = askBuoyStore.getState();
29
+ const ledger = askBuoyStore.getLedger();
30
+ const entries = ledger?.list() ?? [];
31
+ const outstanding = entries.filter(e => !e.undoneAt);
32
+ return {
33
+ version: ASK_BUOY_ADAPTER_VERSION,
34
+ busy: state.busy,
35
+ configured: state.configured,
36
+ notice: state.notice,
37
+ messageCount: state.messages.length,
38
+ // Only the shape of the conversation, never tool payloads.
39
+ messages: state.messages.map(m => ({
40
+ id: m.id,
41
+ role: m.role,
42
+ text: redactForWire(m.text),
43
+ streaming: !!m.streaming,
44
+ toolCalls: m.toolCalls.map(c => ({
45
+ toolId: c.toolId,
46
+ action: c.action,
47
+ status: c.status
48
+ }))
49
+ })),
50
+ // Session token totals, so a desktop/MCP observer can meter cost.
51
+ usage: state.usage,
52
+ pendingApproval: state.pending ? {
53
+ toolId: state.pending.toolId,
54
+ action: state.pending.action,
55
+ label: state.pending.label
56
+ } : null,
57
+ changes: {
58
+ // Transients (navigation, taps) are one-shot actions, not changes —
59
+ // same rule as the on-device bar, so desktop and device tell one story.
60
+ reversible: outstanding.filter(e => isReversible(e.effect)).length,
61
+ permanent: outstanding.filter(e => e.effect.kind !== "transient" && !isReversible(e.effect)).length,
62
+ transients: outstanding.filter(e => e.effect.kind === "transient").length,
63
+ items: outstanding.map(e => ({
64
+ kind: e.effect.kind,
65
+ label: e.effect.label
66
+ }))
67
+ }
68
+ };
69
+ },
70
+ subscribe(onChange) {
71
+ const offStore = askBuoyStore.subscribe(onChange);
72
+ const offLedger = askBuoyStore.getLedger()?.subscribe(onChange);
73
+ return () => {
74
+ offStore();
75
+ offLedger?.();
76
+ };
77
+ },
78
+ actions: {
79
+ /** What the agent changed, and whether it can be put back. */
80
+ listChanges: () => {
81
+ const entries = askBuoyStore.getLedger()?.list() ?? [];
82
+ return entries.filter(e => !e.undoneAt).map(e => ({
83
+ id: e.id,
84
+ at: e.at,
85
+ toolId: e.toolId,
86
+ action: e.action,
87
+ kind: e.effect.kind,
88
+ label: e.effect.label,
89
+ reversible: isReversible(e.effect)
90
+ }));
91
+ },
92
+ /** Put back everything that can be put back. Safe direction only. */
93
+ undoAll: async () => {
94
+ const ledger = askBuoyStore.getLedger();
95
+ if (!ledger) return {
96
+ ok: false,
97
+ error: "No Ask Buoy session on this device."
98
+ };
99
+ const outcome = await ledger.revertAll(dispatchToolAction);
100
+ return {
101
+ ok: true,
102
+ ...outcome
103
+ };
104
+ },
105
+ /** Clear the transcript and the ledger. Does not undo anything. */
106
+ reset: () => {
107
+ askBuoyStore.reset();
108
+ return {
109
+ ok: true
110
+ };
111
+ }
112
+ }
113
+ };
114
+ //# sourceMappingURL=askBuoySyncAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["dispatchToolAction","redactForWire","isReversible","askBuoyStore","ASK_BUOY_ADAPTER_VERSION","askBuoySyncAdapter","version","getSnapshot","state","getState","ledger","getLedger","entries","list","outstanding","filter","e","undoneAt","busy","configured","notice","messageCount","messages","length","map","m","id","role","text","streaming","toolCalls","c","toolId","action","status","usage","pendingApproval","pending","label","changes","reversible","effect","permanent","kind","transients","items","subscribe","onChange","offStore","offLedger","actions","listChanges","at","undoAll","ok","error","outcome","revertAll","reset"],"sourceRoot":"../../../src","sources":["sync/askBuoySyncAdapter.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * What Ask Buoy is allowed to put on the broker wire, and what it refuses to
5
+ * accept from it.
6
+ *
7
+ * Both directions matter. The broker has no authentication, accepts any client
8
+ * that calls itself "Dashboard", and forwards to every connected dashboard — it
9
+ * already broadcasts license keys that way. So: no tool results go out, and no
10
+ * remote client can make the agent say anything.
11
+ */
12
+ import { beforeEach, describe, expect, it } from "vitest";
13
+ import { EffectLedger } from "@buoy-gg/agent-core";
14
+ import { askBuoySyncAdapter } from "./askBuoySyncAdapter";
15
+ import { redactForWire } from "./wire";
16
+ import { askBuoyStore } from "../store/askBuoyStore";
17
+ beforeEach(() => {
18
+ askBuoyStore.reset();
19
+ askBuoyStore.setLedger(null);
20
+ });
21
+ describe("the wire surface", () => {
22
+ it("exposes no action that can make the agent talk", () => {
23
+ // A `send` here would let anyone on the LAN drive a mutating agent on a
24
+ // tester's phone. The conversation starts on-device, by a person.
25
+ const actions = Object.keys(askBuoySyncAdapter.actions);
26
+ expect(actions).not.toContain("send");
27
+ expect(actions).not.toContain("ask");
28
+ expect(actions).not.toContain("prompt");
29
+ expect(actions.sort()).toEqual(["listChanges", "reset", "undoAll"]);
30
+ });
31
+ it("puts the shape of the conversation on the wire, never tool payloads", () => {
32
+ askBuoyStore.addUser("what is in storage");
33
+ const id = askBuoyStore.startAssistant();
34
+ askBuoyStore.applyEvent(id, {
35
+ type: "tool-start",
36
+ id: "c1",
37
+ toolId: "storage",
38
+ action: "async.getItem",
39
+ label: "Read session",
40
+ description: "Read one AsyncStorage key"
41
+ });
42
+ askBuoyStore.applyEvent(id, {
43
+ type: "tool-end",
44
+ id: "c1",
45
+ ok: true,
46
+ summary: "eyJhbGciOiJIUzI1NiJ9.super.secret"
47
+ });
48
+ const snap = askBuoySyncAdapter.getSnapshot();
49
+ const call = snap.messages[1].toolCalls[0];
50
+ expect(call).toEqual({
51
+ toolId: "storage",
52
+ action: "async.getItem",
53
+ status: "ok"
54
+ });
55
+ // The result summary is not on the wire at all — there is no field for it.
56
+ expect(JSON.stringify(snap)).not.toContain("super.secret");
57
+ });
58
+ it("redacts credentials that made it into the assistant's prose", () => {
59
+ askBuoyStore.addUser("show me the auth header");
60
+ const id = askBuoyStore.startAssistant();
61
+ askBuoyStore.applyEvent(id, {
62
+ type: "text",
63
+ delta: "It sends Authorization: Bearer abcdef0123456789ghijkl to the API."
64
+ });
65
+ const snap = askBuoySyncAdapter.getSnapshot();
66
+ expect(JSON.stringify(snap)).not.toContain("abcdef0123456789ghijkl");
67
+ });
68
+ it("reports reversible and permanent changes separately", () => {
69
+ const ledger = new EffectLedger();
70
+ askBuoyStore.setLedger(ledger);
71
+ ledger.record("storage", "async.setItem", {
72
+ kind: "storage-write",
73
+ toolId: "storage",
74
+ action: "async.setItem",
75
+ key: "points",
76
+ before: "240",
77
+ label: "Set points to 1500"
78
+ });
79
+ ledger.record("perf-monitor", "clearAll", {
80
+ kind: "transient",
81
+ label: "Cleared samples"
82
+ });
83
+ // A store write with no captured prior state: recorded, visible, and
84
+ // NOT something Undo can deliver — it must count as permanent.
85
+ ledger.record("zustand", "setState", {
86
+ kind: "state-write",
87
+ toolId: "zustand",
88
+ action: "setState",
89
+ label: "Update the cart store"
90
+ });
91
+ const snap = askBuoySyncAdapter.getSnapshot();
92
+ expect(snap.changes.reversible).toBe(1);
93
+ // The transient is an ACTION, not a change — it must not inflate
94
+ // "permanent" (that read "Changed this app · N permanent" after a
95
+ // read-only tour). It is still reported, in its own count.
96
+ expect(snap.changes.permanent).toBe(1);
97
+ expect(snap.changes.transients).toBe(1);
98
+ });
99
+ });
100
+ describe("redactForWire", () => {
101
+ it("removes bearer tokens, JWTs, api keys and license keys", () => {
102
+ const cases = ["Authorization: Bearer abcdefghijklmnop123456", "token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9abcdefgh", "key sk-abcdefghijklmnop1234", "license BUOY-ABCD-1234-EFGH", 'the header is "x-api-key": "supersecretvalue"'];
103
+ for (const input of cases) {
104
+ expect(redactForWire(input)).toContain("removed]");
105
+ }
106
+ });
107
+ it("leaves ordinary prose alone", () => {
108
+ const text = "The /menu call returned 200 with 12 items and the burger was in stock.";
109
+ expect(redactForWire(text)).toBe(text);
110
+ });
111
+ });
112
+ describe("undo from the desktop", () => {
113
+ it("is allowed, because putting things back is the safe direction", async () => {
114
+ const ledger = new EffectLedger();
115
+ askBuoyStore.setLedger(ledger);
116
+ const store = new Map([["points", "1500"]]);
117
+ ledger.record("storage", "async.setItem", {
118
+ kind: "storage-write",
119
+ toolId: "storage",
120
+ action: "async.setItem",
121
+ key: "points",
122
+ before: "240",
123
+ label: "Set points to 1500"
124
+ });
125
+
126
+ // The adapter dispatches through the real seam; stub it at the ledger.
127
+ await ledger.revertAll(async (_t, action, params) => {
128
+ const p = params;
129
+ if (action === "async.setItem") store.set(p.key, p.value);
130
+ return undefined;
131
+ });
132
+ expect(store.get("points")).toBe("240");
133
+ });
134
+ });
135
+ //# sourceMappingURL=askBuoySyncAdapter.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["beforeEach","describe","expect","it","EffectLedger","askBuoySyncAdapter","redactForWire","askBuoyStore","reset","setLedger","actions","Object","keys","not","toContain","sort","toEqual","addUser","id","startAssistant","applyEvent","type","toolId","action","label","description","ok","summary","snap","getSnapshot","call","messages","toolCalls","status","JSON","stringify","delta","ledger","record","kind","key","before","changes","reversible","toBe","permanent","transients","cases","input","text","store","Map","revertAll","_t","params","p","set","value","undefined","get"],"sourceRoot":"../../../src","sources":["sync/askBuoySyncAdapter.test.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * What the sync adapter is allowed to put on the broker wire.
5
+ *
6
+ * The broker has no authentication, `cors.origin: "*"`, binds every interface,
7
+ * and forwards to every connected dashboard — it already broadcasts each
8
+ * device's license key to every socket. A chat transcript is not a safe thing
9
+ * to add to that channel unfiltered: the agent reads storage values, network
10
+ * response bodies and user records, and any of it can end up quoted in an
11
+ * answer.
12
+ *
13
+ * So text crossing the wire is scrubbed for the shapes that are unambiguously
14
+ * credentials. This is a reduction in blast radius, not a guarantee — the real
15
+ * guarantee is that tool RESULTS never cross at all (see askBuoySyncAdapter).
16
+ */
17
+ export { dispatchToolAction } from "@buoy-gg/shared-ui";
18
+ const PATTERNS = [{
19
+ re: /\bBearer\s+[A-Za-z0-9._~+/-]{12,}=*/gi,
20
+ label: "[bearer token removed]"
21
+ }, {
22
+ re: /\beyJ[A-Za-z0-9._-]{20,}/g,
23
+ label: "[jwt removed]"
24
+ }, {
25
+ re: /\bsk-[A-Za-z0-9_-]{16,}/g,
26
+ label: "[api key removed]"
27
+ }, {
28
+ re: /\bBUOY-[A-Z0-9-]{8,}/g,
29
+ label: "[license key removed]"
30
+ },
31
+ // Common "key: value" credential shapes in a quoted payload.
32
+ {
33
+ re: /("|')?(authorization|x-api-key|api[_-]?key|password|secret|access_token|refresh_token)\1?\s*[:=]\s*("|')?[^\s"',}]{6,}/gi,
34
+ label: "[credential removed]"
35
+ }];
36
+ export function redactForWire(text) {
37
+ if (!text) return text;
38
+ let out = text;
39
+ for (const {
40
+ re,
41
+ label
42
+ } of PATTERNS) {
43
+ out = out.replace(re, label);
44
+ }
45
+ return out;
46
+ }
47
+ //# sourceMappingURL=wire.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["dispatchToolAction","PATTERNS","re","label","redactForWire","text","out","replace"],"sourceRoot":"../../../src","sources":["sync/wire.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASA,kBAAkB,QAAQ,oBAAoB;AAEvD,MAAMC,QAAyC,GAAG,CAChD;EAAEC,EAAE,EAAE,uCAAuC;EAAEC,KAAK,EAAE;AAAyB,CAAC,EAChF;EAAED,EAAE,EAAE,2BAA2B;EAAEC,KAAK,EAAE;AAAgB,CAAC,EAC3D;EAAED,EAAE,EAAE,0BAA0B;EAAEC,KAAK,EAAE;AAAoB,CAAC,EAC9D;EAAED,EAAE,EAAE,uBAAuB;EAAEC,KAAK,EAAE;AAAwB,CAAC;AAC/D;AACA;EACED,EAAE,EAAE,0HAA0H;EAC9HC,KAAK,EAAE;AACT,CAAC,CACF;AAED,OAAO,SAASC,aAAaA,CAACC,IAAY,EAAU;EAClD,IAAI,CAACA,IAAI,EAAE,OAAOA,IAAI;EACtB,IAAIC,GAAG,GAAGD,IAAI;EACd,KAAK,MAAM;IAAEH,EAAE;IAAEC;EAAM,CAAC,IAAIF,QAAQ,EAAE;IACpCK,GAAG,GAAGA,GAAG,CAACC,OAAO,CAACL,EAAE,EAAEC,KAAK,CAAC;EAC9B;EACA,OAAOG,GAAG;AACZ","ignoreList":[]}
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+
3
+ export {};
4
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sourceRoot":"../../src","sources":["types.ts"],"mappings":"","ignoreList":[]}
@@ -0,0 +1,11 @@
1
+ import type { ChoiceBlock, ConfirmBlock, InputBlock } from "@buoy-gg/agent-core";
2
+ export declare function Choice({ block }: {
3
+ block: ChoiceBlock;
4
+ }): import("react").JSX.Element;
5
+ export declare function Confirm({ block }: {
6
+ block: ConfirmBlock;
7
+ }): import("react").JSX.Element;
8
+ export declare function Input({ block }: {
9
+ block: InputBlock;
10
+ }): import("react").JSX.Element;
11
+ //# sourceMappingURL=AskBlocks.d.ts.map