@buoy-gg/ask-buoy 7.0.40 → 7.0.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (314) hide show
  1. package/README.md +13 -94
  2. package/lib/commonjs/blocks/AskBlocks.js +1 -338
  3. package/lib/commonjs/blocks/BlockRenderer.js +1 -262
  4. package/lib/commonjs/blocks/ChromePrototypes.js +1 -514
  5. package/lib/commonjs/blocks/DataBlocks.js +1 -781
  6. package/lib/commonjs/blocks/ExtraBlocks.js +1 -1860
  7. package/lib/commonjs/blocks/MediaBlocks.js +1 -156
  8. package/lib/commonjs/blocks/ReceiptBlocks.js +2 -586
  9. package/lib/commonjs/blocks/blockText.js +1 -60
  10. package/lib/commonjs/blocks/blockText.test.js +1 -53
  11. package/lib/commonjs/blocks/context.js +1 -42
  12. package/lib/commonjs/blocks/icons.js +1 -96
  13. package/lib/commonjs/blocks/index.js +1 -95
  14. package/lib/commonjs/blocks/listRow.test.js +1 -55
  15. package/lib/commonjs/blocks/pageState.js +1 -34
  16. package/lib/commonjs/blocks/pageState.test.js +1 -57
  17. package/lib/commonjs/blocks/primitives.js +1 -457
  18. package/lib/commonjs/blocks/primitivesIndex.js +1 -62
  19. package/lib/commonjs/blocks/ruleStates.js +1 -0
  20. package/lib/commonjs/components/ApprovalCard.js +1 -297
  21. package/lib/commonjs/components/AskBuoyHeader.js +1 -196
  22. package/lib/commonjs/components/AskBuoyIcon.js +1 -19
  23. package/lib/commonjs/components/AskBuoyModal.js +2 -478
  24. package/lib/commonjs/components/AskBuoySettings.js +1 -181
  25. package/lib/commonjs/components/ChangesBar.js +1 -211
  26. package/lib/commonjs/components/Composer.js +1 -255
  27. package/lib/commonjs/components/EmptyState.js +1 -161
  28. package/lib/commonjs/components/KeyboardPad.js +1 -80
  29. package/lib/commonjs/components/Markdown.js +1 -310
  30. package/lib/commonjs/components/MessageList.js +1 -970
  31. package/lib/commonjs/components/QueuedMessages.js +1 -145
  32. package/lib/commonjs/components/ThinkingStrip.js +1 -223
  33. package/lib/commonjs/components/TypingDots.js +1 -63
  34. package/lib/commonjs/components/markdownParse.js +1 -131
  35. package/lib/commonjs/components/markdownParse.test.js +1 -99
  36. package/lib/commonjs/components/useCopyAction.js +1 -50
  37. package/lib/commonjs/index.js +1 -252
  38. package/lib/commonjs/preset.js +1 -91
  39. package/lib/commonjs/store/activityGroups.js +1 -110
  40. package/lib/commonjs/store/activityGroups.test.js +1 -78
  41. package/lib/commonjs/store/askBuoySettings.js +1 -72
  42. package/lib/commonjs/store/askBuoyStore.js +2 -588
  43. package/lib/commonjs/store/blockPlacement.js +1 -64
  44. package/lib/commonjs/store/blockPlacement.test.js +1 -123
  45. package/lib/commonjs/store/queue.test.js +1 -150
  46. package/lib/commonjs/store/resetConversation.js +1 -77
  47. package/lib/commonjs/store/restorePending.test.js +1 -63
  48. package/lib/commonjs/store/restoredIds.test.js +1 -47
  49. package/lib/commonjs/store/suggestions.js +1 -54
  50. package/lib/commonjs/store/suggestions.test.js +1 -58
  51. package/lib/commonjs/store/systemLine.test.js +1 -77
  52. package/lib/commonjs/store/ticketPrompt.js +1 -17
  53. package/lib/commonjs/store/traceText.js +1 -81
  54. package/lib/commonjs/store/traceText.test.js +1 -112
  55. package/lib/commonjs/store/transcriptPersistence.js +1 -297
  56. package/lib/commonjs/store/transcriptPersistence.test.js +1 -333
  57. package/lib/commonjs/store/turnRendering.test.js +1 -151
  58. package/lib/commonjs/store/useAskBuoy.js +1 -651
  59. package/lib/commonjs/store/useAskBuoySettings.js +1 -14
  60. package/lib/commonjs/sync/askBuoySyncAdapter.js +1 -153
  61. package/lib/commonjs/sync/askBuoySyncAdapter.test.js +1 -141
  62. package/lib/commonjs/sync/wire.js +1 -58
  63. package/lib/commonjs/types.js +1 -6
  64. package/lib/module/blocks/AskBlocks.js +1 -331
  65. package/lib/module/blocks/BlockRenderer.js +1 -257
  66. package/lib/module/blocks/ChromePrototypes.js +1 -503
  67. package/lib/module/blocks/DataBlocks.js +1 -767
  68. package/lib/module/blocks/ExtraBlocks.js +1 -1833
  69. package/lib/module/blocks/MediaBlocks.js +1 -151
  70. package/lib/module/blocks/ReceiptBlocks.js +2 -574
  71. package/lib/module/blocks/blockText.js +1 -55
  72. package/lib/module/blocks/blockText.test.js +1 -53
  73. package/lib/module/blocks/context.js +1 -35
  74. package/lib/module/blocks/icons.js +1 -91
  75. package/lib/module/blocks/index.js +1 -8
  76. package/lib/module/blocks/listRow.test.js +1 -56
  77. package/lib/module/blocks/pageState.js +1 -30
  78. package/lib/module/blocks/pageState.test.js +1 -56
  79. package/lib/module/blocks/primitives.js +1 -445
  80. package/lib/module/blocks/primitivesIndex.js +1 -5
  81. package/lib/module/blocks/ruleStates.js +1 -0
  82. package/lib/module/components/ApprovalCard.js +1 -292
  83. package/lib/module/components/AskBuoyHeader.js +1 -193
  84. package/lib/module/components/AskBuoyIcon.js +1 -8
  85. package/lib/module/components/AskBuoyModal.js +2 -473
  86. package/lib/module/components/AskBuoySettings.js +1 -176
  87. package/lib/module/components/ChangesBar.js +1 -206
  88. package/lib/module/components/Composer.js +1 -250
  89. package/lib/module/components/EmptyState.js +1 -156
  90. package/lib/module/components/KeyboardPad.js +1 -75
  91. package/lib/module/components/Markdown.js +1 -305
  92. package/lib/module/components/MessageList.js +1 -964
  93. package/lib/module/components/QueuedMessages.js +1 -140
  94. package/lib/module/components/ThinkingStrip.js +1 -218
  95. package/lib/module/components/TypingDots.js +1 -58
  96. package/lib/module/components/markdownParse.js +1 -125
  97. package/lib/module/components/markdownParse.test.js +1 -98
  98. package/lib/module/components/useCopyAction.js +1 -46
  99. package/lib/module/index.js +1 -34
  100. package/lib/module/preset.js +1 -74
  101. package/lib/module/store/activityGroups.js +1 -103
  102. package/lib/module/store/activityGroups.test.js +1 -77
  103. package/lib/module/store/askBuoySettings.js +1 -67
  104. package/lib/module/store/askBuoyStore.js +2 -582
  105. package/lib/module/store/blockPlacement.js +1 -59
  106. package/lib/module/store/blockPlacement.test.js +1 -122
  107. package/lib/module/store/queue.test.js +1 -149
  108. package/lib/module/store/resetConversation.js +1 -72
  109. package/lib/module/store/restorePending.test.js +1 -62
  110. package/lib/module/store/restoredIds.test.js +1 -46
  111. package/lib/module/store/suggestions.js +1 -49
  112. package/lib/module/store/suggestions.test.js +1 -57
  113. package/lib/module/store/systemLine.test.js +1 -76
  114. package/lib/module/store/ticketPrompt.js +1 -13
  115. package/lib/module/store/traceText.js +1 -75
  116. package/lib/module/store/traceText.test.js +1 -111
  117. package/lib/module/store/transcriptPersistence.js +1 -287
  118. package/lib/module/store/transcriptPersistence.test.js +1 -332
  119. package/lib/module/store/turnRendering.test.js +1 -150
  120. package/lib/module/store/useAskBuoy.js +1 -646
  121. package/lib/module/store/useAskBuoySettings.js +1 -9
  122. package/lib/module/sync/askBuoySyncAdapter.js +1 -148
  123. package/lib/module/sync/askBuoySyncAdapter.test.js +1 -140
  124. package/lib/module/sync/wire.js +1 -47
  125. package/lib/module/types.js +1 -4
  126. package/lib/typescript/blocks/context.d.ts +3 -0
  127. package/lib/typescript/blocks/ruleStates.d.ts +15 -0
  128. package/lib/typescript/components/ChangesBar.d.ts +2 -1
  129. package/lib/typescript/sync/askBuoySyncAdapter.d.ts +2 -2
  130. package/lib/web/index.mjs +15 -0
  131. package/package.json +44 -11
  132. package/lib/commonjs/blocks/AskBlocks.js.map +0 -1
  133. package/lib/commonjs/blocks/BlockRenderer.js.map +0 -1
  134. package/lib/commonjs/blocks/ChromePrototypes.js.map +0 -1
  135. package/lib/commonjs/blocks/DataBlocks.js.map +0 -1
  136. package/lib/commonjs/blocks/ExtraBlocks.js.map +0 -1
  137. package/lib/commonjs/blocks/MediaBlocks.js.map +0 -1
  138. package/lib/commonjs/blocks/ReceiptBlocks.js.map +0 -1
  139. package/lib/commonjs/blocks/blockText.js.map +0 -1
  140. package/lib/commonjs/blocks/blockText.test.js.map +0 -1
  141. package/lib/commonjs/blocks/context.js.map +0 -1
  142. package/lib/commonjs/blocks/icons.js.map +0 -1
  143. package/lib/commonjs/blocks/index.js.map +0 -1
  144. package/lib/commonjs/blocks/listRow.test.js.map +0 -1
  145. package/lib/commonjs/blocks/pageState.js.map +0 -1
  146. package/lib/commonjs/blocks/pageState.test.js.map +0 -1
  147. package/lib/commonjs/blocks/primitives.js.map +0 -1
  148. package/lib/commonjs/blocks/primitivesIndex.js.map +0 -1
  149. package/lib/commonjs/components/ApprovalCard.js.map +0 -1
  150. package/lib/commonjs/components/AskBuoyHeader.js.map +0 -1
  151. package/lib/commonjs/components/AskBuoyIcon.js.map +0 -1
  152. package/lib/commonjs/components/AskBuoyModal.js.map +0 -1
  153. package/lib/commonjs/components/AskBuoySettings.js.map +0 -1
  154. package/lib/commonjs/components/ChangesBar.js.map +0 -1
  155. package/lib/commonjs/components/Composer.js.map +0 -1
  156. package/lib/commonjs/components/EmptyState.js.map +0 -1
  157. package/lib/commonjs/components/KeyboardPad.js.map +0 -1
  158. package/lib/commonjs/components/Markdown.js.map +0 -1
  159. package/lib/commonjs/components/MessageList.js.map +0 -1
  160. package/lib/commonjs/components/QueuedMessages.js.map +0 -1
  161. package/lib/commonjs/components/ThinkingStrip.js.map +0 -1
  162. package/lib/commonjs/components/TypingDots.js.map +0 -1
  163. package/lib/commonjs/components/markdownParse.js.map +0 -1
  164. package/lib/commonjs/components/markdownParse.test.js.map +0 -1
  165. package/lib/commonjs/components/useCopyAction.js.map +0 -1
  166. package/lib/commonjs/index.js.map +0 -1
  167. package/lib/commonjs/preset.js.map +0 -1
  168. package/lib/commonjs/store/activityGroups.js.map +0 -1
  169. package/lib/commonjs/store/activityGroups.test.js.map +0 -1
  170. package/lib/commonjs/store/askBuoySettings.js.map +0 -1
  171. package/lib/commonjs/store/askBuoyStore.js.map +0 -1
  172. package/lib/commonjs/store/blockPlacement.js.map +0 -1
  173. package/lib/commonjs/store/blockPlacement.test.js.map +0 -1
  174. package/lib/commonjs/store/queue.test.js.map +0 -1
  175. package/lib/commonjs/store/resetConversation.js.map +0 -1
  176. package/lib/commonjs/store/restorePending.test.js.map +0 -1
  177. package/lib/commonjs/store/restoredIds.test.js.map +0 -1
  178. package/lib/commonjs/store/suggestions.js.map +0 -1
  179. package/lib/commonjs/store/suggestions.test.js.map +0 -1
  180. package/lib/commonjs/store/systemLine.test.js.map +0 -1
  181. package/lib/commonjs/store/ticketPrompt.js.map +0 -1
  182. package/lib/commonjs/store/traceText.js.map +0 -1
  183. package/lib/commonjs/store/traceText.test.js.map +0 -1
  184. package/lib/commonjs/store/transcriptPersistence.js.map +0 -1
  185. package/lib/commonjs/store/transcriptPersistence.test.js.map +0 -1
  186. package/lib/commonjs/store/turnRendering.test.js.map +0 -1
  187. package/lib/commonjs/store/useAskBuoy.js.map +0 -1
  188. package/lib/commonjs/store/useAskBuoySettings.js.map +0 -1
  189. package/lib/commonjs/sync/askBuoySyncAdapter.js.map +0 -1
  190. package/lib/commonjs/sync/askBuoySyncAdapter.test.js.map +0 -1
  191. package/lib/commonjs/sync/wire.js.map +0 -1
  192. package/lib/commonjs/types.js.map +0 -1
  193. package/lib/module/blocks/AskBlocks.js.map +0 -1
  194. package/lib/module/blocks/BlockRenderer.js.map +0 -1
  195. package/lib/module/blocks/ChromePrototypes.js.map +0 -1
  196. package/lib/module/blocks/DataBlocks.js.map +0 -1
  197. package/lib/module/blocks/ExtraBlocks.js.map +0 -1
  198. package/lib/module/blocks/MediaBlocks.js.map +0 -1
  199. package/lib/module/blocks/ReceiptBlocks.js.map +0 -1
  200. package/lib/module/blocks/blockText.js.map +0 -1
  201. package/lib/module/blocks/blockText.test.js.map +0 -1
  202. package/lib/module/blocks/context.js.map +0 -1
  203. package/lib/module/blocks/icons.js.map +0 -1
  204. package/lib/module/blocks/index.js.map +0 -1
  205. package/lib/module/blocks/listRow.test.js.map +0 -1
  206. package/lib/module/blocks/pageState.js.map +0 -1
  207. package/lib/module/blocks/pageState.test.js.map +0 -1
  208. package/lib/module/blocks/primitives.js.map +0 -1
  209. package/lib/module/blocks/primitivesIndex.js.map +0 -1
  210. package/lib/module/components/ApprovalCard.js.map +0 -1
  211. package/lib/module/components/AskBuoyHeader.js.map +0 -1
  212. package/lib/module/components/AskBuoyIcon.js.map +0 -1
  213. package/lib/module/components/AskBuoyModal.js.map +0 -1
  214. package/lib/module/components/AskBuoySettings.js.map +0 -1
  215. package/lib/module/components/ChangesBar.js.map +0 -1
  216. package/lib/module/components/Composer.js.map +0 -1
  217. package/lib/module/components/EmptyState.js.map +0 -1
  218. package/lib/module/components/KeyboardPad.js.map +0 -1
  219. package/lib/module/components/Markdown.js.map +0 -1
  220. package/lib/module/components/MessageList.js.map +0 -1
  221. package/lib/module/components/QueuedMessages.js.map +0 -1
  222. package/lib/module/components/ThinkingStrip.js.map +0 -1
  223. package/lib/module/components/TypingDots.js.map +0 -1
  224. package/lib/module/components/markdownParse.js.map +0 -1
  225. package/lib/module/components/markdownParse.test.js.map +0 -1
  226. package/lib/module/components/useCopyAction.js.map +0 -1
  227. package/lib/module/index.js.map +0 -1
  228. package/lib/module/preset.js.map +0 -1
  229. package/lib/module/store/activityGroups.js.map +0 -1
  230. package/lib/module/store/activityGroups.test.js.map +0 -1
  231. package/lib/module/store/askBuoySettings.js.map +0 -1
  232. package/lib/module/store/askBuoyStore.js.map +0 -1
  233. package/lib/module/store/blockPlacement.js.map +0 -1
  234. package/lib/module/store/blockPlacement.test.js.map +0 -1
  235. package/lib/module/store/queue.test.js.map +0 -1
  236. package/lib/module/store/resetConversation.js.map +0 -1
  237. package/lib/module/store/restorePending.test.js.map +0 -1
  238. package/lib/module/store/restoredIds.test.js.map +0 -1
  239. package/lib/module/store/suggestions.js.map +0 -1
  240. package/lib/module/store/suggestions.test.js.map +0 -1
  241. package/lib/module/store/systemLine.test.js.map +0 -1
  242. package/lib/module/store/ticketPrompt.js.map +0 -1
  243. package/lib/module/store/traceText.js.map +0 -1
  244. package/lib/module/store/traceText.test.js.map +0 -1
  245. package/lib/module/store/transcriptPersistence.js.map +0 -1
  246. package/lib/module/store/transcriptPersistence.test.js.map +0 -1
  247. package/lib/module/store/turnRendering.test.js.map +0 -1
  248. package/lib/module/store/useAskBuoy.js.map +0 -1
  249. package/lib/module/store/useAskBuoySettings.js.map +0 -1
  250. package/lib/module/sync/askBuoySyncAdapter.js.map +0 -1
  251. package/lib/module/sync/askBuoySyncAdapter.test.js.map +0 -1
  252. package/lib/module/sync/wire.js.map +0 -1
  253. package/lib/module/types.js.map +0 -1
  254. package/lib/typescript/blocks/AskBlocks.d.ts.map +0 -1
  255. package/lib/typescript/blocks/BlockRenderer.d.ts.map +0 -1
  256. package/lib/typescript/blocks/ChromePrototypes.d.ts.map +0 -1
  257. package/lib/typescript/blocks/DataBlocks.d.ts.map +0 -1
  258. package/lib/typescript/blocks/ExtraBlocks.d.ts.map +0 -1
  259. package/lib/typescript/blocks/MediaBlocks.d.ts.map +0 -1
  260. package/lib/typescript/blocks/ReceiptBlocks.d.ts.map +0 -1
  261. package/lib/typescript/blocks/blockText.d.ts.map +0 -1
  262. package/lib/typescript/blocks/blockText.test.d.ts.map +0 -1
  263. package/lib/typescript/blocks/context.d.ts.map +0 -1
  264. package/lib/typescript/blocks/icons.d.ts.map +0 -1
  265. package/lib/typescript/blocks/index.d.ts.map +0 -1
  266. package/lib/typescript/blocks/listRow.test.d.ts.map +0 -1
  267. package/lib/typescript/blocks/pageState.d.ts.map +0 -1
  268. package/lib/typescript/blocks/pageState.test.d.ts.map +0 -1
  269. package/lib/typescript/blocks/primitives.d.ts.map +0 -1
  270. package/lib/typescript/blocks/primitivesIndex.d.ts.map +0 -1
  271. package/lib/typescript/components/ApprovalCard.d.ts.map +0 -1
  272. package/lib/typescript/components/AskBuoyHeader.d.ts.map +0 -1
  273. package/lib/typescript/components/AskBuoyIcon.d.ts.map +0 -1
  274. package/lib/typescript/components/AskBuoyModal.d.ts.map +0 -1
  275. package/lib/typescript/components/AskBuoySettings.d.ts.map +0 -1
  276. package/lib/typescript/components/ChangesBar.d.ts.map +0 -1
  277. package/lib/typescript/components/Composer.d.ts.map +0 -1
  278. package/lib/typescript/components/EmptyState.d.ts.map +0 -1
  279. package/lib/typescript/components/KeyboardPad.d.ts.map +0 -1
  280. package/lib/typescript/components/Markdown.d.ts.map +0 -1
  281. package/lib/typescript/components/MessageList.d.ts.map +0 -1
  282. package/lib/typescript/components/QueuedMessages.d.ts.map +0 -1
  283. package/lib/typescript/components/ThinkingStrip.d.ts.map +0 -1
  284. package/lib/typescript/components/TypingDots.d.ts.map +0 -1
  285. package/lib/typescript/components/markdownParse.d.ts.map +0 -1
  286. package/lib/typescript/components/markdownParse.test.d.ts.map +0 -1
  287. package/lib/typescript/components/useCopyAction.d.ts.map +0 -1
  288. package/lib/typescript/index.d.ts.map +0 -1
  289. package/lib/typescript/preset.d.ts.map +0 -1
  290. package/lib/typescript/store/activityGroups.d.ts.map +0 -1
  291. package/lib/typescript/store/activityGroups.test.d.ts.map +0 -1
  292. package/lib/typescript/store/askBuoySettings.d.ts.map +0 -1
  293. package/lib/typescript/store/askBuoyStore.d.ts.map +0 -1
  294. package/lib/typescript/store/blockPlacement.d.ts.map +0 -1
  295. package/lib/typescript/store/blockPlacement.test.d.ts.map +0 -1
  296. package/lib/typescript/store/queue.test.d.ts.map +0 -1
  297. package/lib/typescript/store/resetConversation.d.ts.map +0 -1
  298. package/lib/typescript/store/restorePending.test.d.ts.map +0 -1
  299. package/lib/typescript/store/restoredIds.test.d.ts.map +0 -1
  300. package/lib/typescript/store/suggestions.d.ts.map +0 -1
  301. package/lib/typescript/store/suggestions.test.d.ts.map +0 -1
  302. package/lib/typescript/store/systemLine.test.d.ts.map +0 -1
  303. package/lib/typescript/store/ticketPrompt.d.ts.map +0 -1
  304. package/lib/typescript/store/traceText.d.ts.map +0 -1
  305. package/lib/typescript/store/traceText.test.d.ts.map +0 -1
  306. package/lib/typescript/store/transcriptPersistence.d.ts.map +0 -1
  307. package/lib/typescript/store/transcriptPersistence.test.d.ts.map +0 -1
  308. package/lib/typescript/store/turnRendering.test.d.ts.map +0 -1
  309. package/lib/typescript/store/useAskBuoy.d.ts.map +0 -1
  310. package/lib/typescript/store/useAskBuoySettings.d.ts.map +0 -1
  311. package/lib/typescript/sync/askBuoySyncAdapter.d.ts.map +0 -1
  312. package/lib/typescript/sync/askBuoySyncAdapter.test.d.ts.map +0 -1
  313. package/lib/typescript/sync/wire.d.ts.map +0 -1
  314. package/lib/typescript/types.d.ts.map +0 -1
@@ -1,148 +1 @@
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 { resetConversation } from "../store/resetConversation";
22
- import { dispatchToolAction, redactForWire } from "./wire";
23
- import { isReversible } from "@buoy-gg/agent-core";
24
- import { askBuoyStore } from "../store/askBuoyStore";
25
- export const ASK_BUOY_ADAPTER_VERSION = 1;
26
- export const askBuoySyncAdapter = {
27
- version: ASK_BUOY_ADAPTER_VERSION,
28
- async dispose(cleanup) {
29
- const ledger = askBuoyStore.getLedger();
30
- for (const entry of ledger?.list() ?? []) {
31
- if (entry.undoneAt) continue;
32
- if (entry.effect.kind === "network-override") {
33
- await cleanup("network", "deleteOverrideRule", {
34
- id: entry.effect.ruleId
35
- });
36
- }
37
- // Impersonation removes its own header without clearing host caches.
38
- // Completed storage/query/state writes remain deliberate developer edits.
39
- }
40
- },
41
- getSnapshot() {
42
- const state = askBuoyStore.getState();
43
- const ledger = askBuoyStore.getLedger();
44
- const entries = ledger?.list() ?? [];
45
- const outstanding = entries.filter(e => !e.undoneAt);
46
- return {
47
- version: ASK_BUOY_ADAPTER_VERSION,
48
- busy: state.busy,
49
- configured: state.configured,
50
- notice: state.notice,
51
- messageCount: state.messages.length,
52
- // Only the shape of the conversation, never tool payloads.
53
- messages: state.messages.map(m => ({
54
- id: m.id,
55
- role: m.role,
56
- text: redactForWire(m.text),
57
- streaming: !!m.streaming,
58
- toolCalls: m.toolCalls.map(c => ({
59
- toolId: c.toolId,
60
- action: c.action,
61
- status: c.status
62
- }))
63
- })),
64
- // Session token totals, so a desktop/MCP observer can meter cost.
65
- usage: state.usage,
66
- pendingApproval: state.pending ? {
67
- toolId: state.pending.toolId,
68
- action: state.pending.action,
69
- label: state.pending.label
70
- } : null,
71
- changes: {
72
- // Transients (navigation, taps) are one-shot actions, not changes —
73
- // same rule as the on-device bar, so desktop and device tell one story.
74
- reversible: outstanding.filter(e => isReversible(e.effect)).length,
75
- permanent: outstanding.filter(e => e.effect.kind !== "transient" && !isReversible(e.effect)).length,
76
- transients: outstanding.filter(e => e.effect.kind === "transient").length,
77
- items: outstanding.map(e => ({
78
- kind: e.effect.kind,
79
- label: e.effect.label
80
- }))
81
- }
82
- };
83
- },
84
- subscribe(onChange) {
85
- const offStore = askBuoyStore.subscribe(onChange);
86
- const offLedger = askBuoyStore.getLedger()?.subscribe(onChange);
87
- return () => {
88
- offStore();
89
- offLedger?.();
90
- };
91
- },
92
- actions: {
93
- /** What the agent changed, and whether it can be put back. */
94
- listChanges: () => {
95
- const entries = askBuoyStore.getLedger()?.list() ?? [];
96
- return entries.filter(e => !e.undoneAt).map(e => ({
97
- id: e.id,
98
- at: e.at,
99
- toolId: e.toolId,
100
- action: e.action,
101
- kind: e.effect.kind,
102
- label: e.effect.label,
103
- reversible: isReversible(e.effect)
104
- }));
105
- },
106
- /** Put back everything that can be put back. Safe direction only. */
107
- undoAll: async () => {
108
- const ledger = askBuoyStore.getLedger();
109
- if (!ledger) return {
110
- ok: false,
111
- error: "No Ask Buoy session on this device."
112
- };
113
- const outcome = await ledger.revertAll(dispatchToolAction);
114
- return {
115
- ok: true,
116
- ...outcome
117
- };
118
- },
119
- /**
120
- * Undo what can be undone, then clear the transcript and the ledger.
121
- *
122
- * The same path as the sheet's "New conversation" (resetConversation.ts).
123
- * This action used to clear unconditionally — no question, no undo — so a
124
- * desktop click could drop the only undo record for changes still live on
125
- * the tester's phone. Now it refuses to clear when a revert fails and says
126
- * what is still applied; the dashboard decides whether to clear anyway
127
- * by calling `undoAll` first or accepting the kept conversation.
128
- */
129
- reset: async () => {
130
- const outcome = await resetConversation({
131
- dispatch: dispatchToolAction,
132
- undoFirst: true
133
- });
134
- if (!outcome.cleared) {
135
- return {
136
- ok: false,
137
- error: `Couldn't undo ${outcome.failed.length} change${outcome.failed.length === 1 ? "" : "s"} — conversation kept.`,
138
- failed: outcome.failed
139
- };
140
- }
141
- return {
142
- ok: true,
143
- reverted: outcome.reverted
144
- };
145
- }
146
- }
147
- };
148
- //# sourceMappingURL=askBuoySyncAdapter.js.map
1
+ "use strict";import{resetConversation as d}from"../store/resetConversation";import{dispatchToolAction as l,redactForWire as c}from"./wire";import{isReversible as a}from"@buoy-gg/agent-core";import{askBuoyStore as r}from"../store/askBuoyStore";export const ASK_BUOY_ADAPTER_VERSION=1;export const askBuoySyncAdapter={version:ASK_BUOY_ADAPTER_VERSION,async dispose(e){const t=r.getLedger();for(const o of t?.list()??[]){if(o.undoneAt)continue;if(o.effect.kind==="network-override"){await e("network","deleteOverrideRule",{id:o.effect.ruleId})}}},getSnapshot(){const e=r.getState();const t=r.getLedger();const o=t?.list()??[];const s=o.filter(n=>!n.undoneAt);return{version:ASK_BUOY_ADAPTER_VERSION,busy:e.busy,configured:e.configured,notice:e.notice,messageCount:e.messages.length,messages:e.messages.map(n=>({id:n.id,role:n.role,text:c(n.text),streaming:!!n.streaming,toolCalls:n.toolCalls.map(i=>({toolId:i.toolId,action:i.action,status:i.status}))})),usage:e.usage,pendingApproval:e.pending?{toolId:e.pending.toolId,action:e.pending.action,label:e.pending.label}:null,changes:{reversible:s.filter(n=>a(n.effect)).length,permanent:s.filter(n=>n.effect.kind!=="transient"&&!a(n.effect)).length,transients:s.filter(n=>n.effect.kind==="transient").length,items:s.map(n=>({kind:n.effect.kind,label:n.effect.label}))}}},subscribe(e){const t=r.subscribe(e);const o=r.getLedger()?.subscribe(e);return()=>{t();o?.()}},actions:{listChanges:()=>{const e=r.getLedger()?.list()??[];return e.filter(t=>!t.undoneAt).map(t=>({id:t.id,at:t.at,toolId:t.toolId,action:t.action,kind:t.effect.kind,label:t.effect.label,reversible:a(t.effect)}))},undoAll:async()=>{const e=r.getLedger();if(!e)return{ok:false,error:"No Ask Buoy session on this device."};const t=await e.revertAll(l);return{ok:true,...t}},reset:async()=>{const e=await d({dispatch:l,undoFirst:true});if(!e.cleared){return{ok:false,error:`Couldn't undo ${e.failed.length} change${e.failed.length===1?"":"s"} \u2014 conversation kept.`,failed:e.failed}}return{ok:true,reverted:e.reverted}}}};
@@ -1,140 +1 @@
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
- params: {
42
- key: "session"
43
- },
44
- effect: "read"
45
- });
46
- askBuoyStore.applyEvent(id, {
47
- type: "tool-end",
48
- id: "c1",
49
- ok: true,
50
- durationMs: 12,
51
- summary: "eyJhbGciOiJIUzI1NiJ9.super.secret"
52
- });
53
- const snap = askBuoySyncAdapter.getSnapshot();
54
- const call = snap.messages[1].toolCalls[0];
55
- expect(call).toEqual({
56
- toolId: "storage",
57
- action: "async.getItem",
58
- status: "ok"
59
- });
60
- // The result summary is not on the wire at all — there is no field for it.
61
- expect(JSON.stringify(snap)).not.toContain("super.secret");
62
- });
63
- it("redacts credentials that made it into the assistant's prose", () => {
64
- askBuoyStore.addUser("show me the auth header");
65
- const id = askBuoyStore.startAssistant();
66
- askBuoyStore.applyEvent(id, {
67
- type: "text",
68
- delta: "It sends Authorization: Bearer abcdef0123456789ghijkl to the API."
69
- });
70
- const snap = askBuoySyncAdapter.getSnapshot();
71
- expect(JSON.stringify(snap)).not.toContain("abcdef0123456789ghijkl");
72
- });
73
- it("reports reversible and permanent changes separately", () => {
74
- const ledger = new EffectLedger();
75
- askBuoyStore.setLedger(ledger);
76
- ledger.record("storage", "async.setItem", {
77
- kind: "storage-write",
78
- toolId: "storage",
79
- action: "async.setItem",
80
- key: "points",
81
- before: "240",
82
- label: "Set points to 1500"
83
- });
84
- ledger.record("perf-monitor", "clearAll", {
85
- kind: "transient",
86
- label: "Cleared samples"
87
- });
88
- // A store write with no captured prior state: recorded, visible, and
89
- // NOT something Undo can deliver — it must count as permanent.
90
- ledger.record("zustand", "setState", {
91
- kind: "state-write",
92
- toolId: "zustand",
93
- action: "setState",
94
- label: "Update the cart store"
95
- });
96
- const snap = askBuoySyncAdapter.getSnapshot();
97
- expect(snap.changes.reversible).toBe(1);
98
- // The transient is an ACTION, not a change — it must not inflate
99
- // "permanent" (that read "Changed this app · N permanent" after a
100
- // read-only tour). It is still reported, in its own count.
101
- expect(snap.changes.permanent).toBe(1);
102
- expect(snap.changes.transients).toBe(1);
103
- });
104
- });
105
- describe("redactForWire", () => {
106
- it("removes bearer tokens, JWTs, api keys and license keys", () => {
107
- const cases = ["Authorization: Bearer abcdefghijklmnop123456", "token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9abcdefgh", "key sk-abcdefghijklmnop1234", "license BUOY-ABCD-1234-EFGH", 'the header is "x-api-key": "supersecretvalue"'];
108
- for (const input of cases) {
109
- expect(redactForWire(input)).toContain("removed]");
110
- }
111
- });
112
- it("leaves ordinary prose alone", () => {
113
- const text = "The /menu call returned 200 with 12 items and the burger was in stock.";
114
- expect(redactForWire(text)).toBe(text);
115
- });
116
- });
117
- describe("undo from the desktop", () => {
118
- it("is allowed, because putting things back is the safe direction", async () => {
119
- const ledger = new EffectLedger();
120
- askBuoyStore.setLedger(ledger);
121
- const store = new Map([["points", "1500"]]);
122
- ledger.record("storage", "async.setItem", {
123
- kind: "storage-write",
124
- toolId: "storage",
125
- action: "async.setItem",
126
- key: "points",
127
- before: "240",
128
- label: "Set points to 1500"
129
- });
130
-
131
- // The adapter dispatches through the real seam; stub it at the ledger.
132
- await ledger.revertAll(async (_t, action, params) => {
133
- const p = params;
134
- if (action === "async.setItem") store.set(p.key, p.value);
135
- return undefined;
136
- });
137
- expect(store.get("points")).toBe("240");
138
- });
139
- });
140
- //# sourceMappingURL=askBuoySyncAdapter.test.js.map
1
+ "use strict";import{beforeEach as g,describe as r,expect as s,it as a}from"vitest";import{EffectLedger as d}from"@buoy-gg/agent-core";import{askBuoySyncAdapter as n}from"./askBuoySyncAdapter";import{redactForWire as l}from"./wire";import{askBuoyStore as o}from"../store/askBuoyStore";g(()=>{o.reset();o.setLedger(null)});r("the wire surface",()=>{a("exposes no action that can make the agent talk",()=>{const e=Object.keys(n.actions);s(e).not.toContain("send");s(e).not.toContain("ask");s(e).not.toContain("prompt");s(e.sort()).toEqual(["listChanges","reset","undoAll"])});a("puts the shape of the conversation on the wire, never tool payloads",()=>{o.addUser("what is in storage");const e=o.startAssistant();o.applyEvent(e,{type:"tool-start",id:"c1",toolId:"storage",action:"async.getItem",label:"Read session",description:"Read one AsyncStorage key",params:{key:"session"},effect:"read"});o.applyEvent(e,{type:"tool-end",id:"c1",ok:true,durationMs:12,summary:"eyJhbGciOiJIUzI1NiJ9.super.secret"});const t=n.getSnapshot();const i=t.messages[1].toolCalls[0];s(i).toEqual({toolId:"storage",action:"async.getItem",status:"ok"});s(JSON.stringify(t)).not.toContain("super.secret")});a("redacts credentials that made it into the assistant's prose",()=>{o.addUser("show me the auth header");const e=o.startAssistant();o.applyEvent(e,{type:"text",delta:"It sends Authorization: Bearer abcdef0123456789ghijkl to the API."});const t=n.getSnapshot();s(JSON.stringify(t)).not.toContain("abcdef0123456789ghijkl")});a("reports reversible and permanent changes separately",()=>{const e=new d;o.setLedger(e);e.record("storage","async.setItem",{kind:"storage-write",toolId:"storage",action:"async.setItem",key:"points",before:"240",label:"Set points to 1500"});e.record("perf-monitor","clearAll",{kind:"transient",label:"Cleared samples"});e.record("zustand","setState",{kind:"state-write",toolId:"zustand",action:"setState",label:"Update the cart store"});const t=n.getSnapshot();s(t.changes.reversible).toBe(1);s(t.changes.permanent).toBe(1);s(t.changes.transients).toBe(1)})});r("redactForWire",()=>{a("removes bearer tokens, JWTs, api keys and license keys",()=>{const e=["Authorization: Bearer abcdefghijklmnop123456","token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9abcdefgh","key sk-abcdefghijklmnop1234","license BUOY-ABCD-1234-EFGH",'the header is "x-api-key": "supersecretvalue"'];for(const t of e){s(l(t)).toContain("removed]")}});a("leaves ordinary prose alone",()=>{const e="The /menu call returned 200 with 12 items and the burger was in stock.";s(l(e)).toBe(e)})});r("undo from the desktop",()=>{a("is allowed, because putting things back is the safe direction",async()=>{const e=new d;o.setLedger(e);const t=new Map([["points","1500"]]);e.record("storage","async.setItem",{kind:"storage-write",toolId:"storage",action:"async.setItem",key:"points",before:"240",label:"Set points to 1500"});await e.revertAll(async(i,p,h)=>{const c=h;if(p==="async.setItem")t.set(c.key,c.value);return void 0});s(t.get("points")).toBe("240")})});
@@ -1,47 +1 @@
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
1
+ "use strict";export{dispatchToolAction}from"@buoy-gg/shared-ui";const t=[{re:/\bBearer\s+[A-Za-z0-9._~+/-]{12,}=*/gi,label:"[bearer token removed]"},{re:/\beyJ[A-Za-z0-9._-]{20,}/g,label:"[jwt removed]"},{re:/\bsk-[A-Za-z0-9_-]{16,}/g,label:"[api key removed]"},{re:/\bBUOY-[A-Z0-9-]{8,}/g,label:"[license key removed]"},{re:/("|')?(authorization|x-api-key|api[_-]?key|password|secret|access_token|refresh_token)\1?\s*[:=]\s*("|')?[^\s"',}]{6,}/gi,label:"[credential removed]"}];export function redactForWire(e){if(!e)return e;let r=e;for(const{re:o,label:a}of t){r=r.replace(o,a)}return r}
@@ -1,4 +1 @@
1
- "use strict";
2
-
3
- export {};
4
- //# sourceMappingURL=types.js.map
1
+ "use strict";export{};
@@ -8,6 +8,7 @@
8
8
  */
9
9
  import { type ReactNode } from "react";
10
10
  import type { BlockAction, BlockAnswer } from "@buoy-gg/agent-core";
11
+ import type { RuleState } from "./ruleStates";
11
12
  export interface BlockHandlers {
12
13
  /** An Ask block was answered. Becomes the next user message. */
13
14
  answer: (answer: BlockAnswer) => void;
@@ -25,6 +26,8 @@ export interface BlockHandlers {
25
26
  minimize?: boolean;
26
27
  dispatch?: boolean;
27
28
  };
29
+ /** Override rules changed since their cards were drawn, by rule id. See ruleStates.ts. */
30
+ rules?: Record<string, RuleState>;
28
31
  }
29
32
  export declare function BlockHandlersProvider({ value, children, }: {
30
33
  value: BlockHandlers;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * What the ledger knows about each override rule since its card was drawn.
3
+ *
4
+ * A rule card is a receipt: it records the rule as the call left it. Undo
5
+ * then deleted the rule and the card kept saying ON, with a "Turn off" button
6
+ * aimed at a rule that no longer existed. The ledger has the later facts, so
7
+ * the card reads them from here instead of trusting its own snapshot.
8
+ */
9
+ import type { LedgerEntry } from "@buoy-gg/agent-core";
10
+ export interface RuleState {
11
+ enabled?: boolean;
12
+ deleted?: boolean;
13
+ }
14
+ export declare function ruleStatesFrom(entries: LedgerEntry[]): Record<string, RuleState>;
15
+ //# sourceMappingURL=ruleStates.d.ts.map
@@ -1,9 +1,10 @@
1
- import { type EffectLedger } from "@buoy-gg/agent-core";
1
+ import { type EffectLedger, type LedgerEntry } from "@buoy-gg/agent-core";
2
2
  export interface ChangesBarProps {
3
3
  ledger: EffectLedger | null;
4
4
  onUndoAll: () => void;
5
5
  expanded: boolean;
6
6
  onToggle: () => void;
7
7
  }
8
+ export declare function useLedgerEntries(ledger: EffectLedger | null): LedgerEntry[];
8
9
  export declare function ChangesBar({ ledger, onUndoAll, expanded, onToggle }: ChangesBarProps): import("react").JSX.Element | null;
9
10
  //# sourceMappingURL=ChangesBar.d.ts.map
@@ -35,7 +35,7 @@ export declare const askBuoySyncAdapter: {
35
35
  permanent: number;
36
36
  transients: number;
37
37
  items: {
38
- kind: "network-override" | "impersonation" | "storage-write" | "query-write" | "state-write" | "transient";
38
+ kind: "network-override" | "impersonation" | "storage-write" | "query-write" | "inverse-call" | "state-write" | "transient";
39
39
  label: string;
40
40
  }[];
41
41
  };
@@ -48,7 +48,7 @@ export declare const askBuoySyncAdapter: {
48
48
  at: number;
49
49
  toolId: string;
50
50
  action: string;
51
- kind: "network-override" | "impersonation" | "storage-write" | "query-write" | "state-write" | "transient";
51
+ kind: "network-override" | "impersonation" | "storage-write" | "query-write" | "inverse-call" | "state-write" | "transient";
52
52
  label: string;
53
53
  reversible: boolean;
54
54
  }[];