@buoy-gg/ask-buoy 7.0.33 → 7.0.34

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 (153) hide show
  1. package/README.md +1 -1
  2. package/lib/commonjs/blocks/AskBlocks.js +1 -338
  3. package/lib/commonjs/blocks/BlockRenderer.js +1 -250
  4. package/lib/commonjs/blocks/ChromePrototypes.js +1 -514
  5. package/lib/commonjs/blocks/DataBlocks.js +1 -545
  6. package/lib/commonjs/blocks/ExtraBlocks.js +1 -1821
  7. package/lib/commonjs/blocks/MediaBlocks.js +1 -140
  8. package/lib/commonjs/blocks/ReceiptBlocks.js +1 -596
  9. package/lib/commonjs/blocks/context.js +1 -42
  10. package/lib/commonjs/blocks/icons.js +1 -96
  11. package/lib/commonjs/blocks/index.js +1 -95
  12. package/lib/commonjs/blocks/primitives.js +1 -312
  13. package/lib/commonjs/blocks/primitivesIndex.js +1 -56
  14. package/lib/commonjs/components/ApprovalCard.js +1 -140
  15. package/lib/commonjs/components/AskBuoyHeader.js +1 -127
  16. package/lib/commonjs/components/AskBuoyIcon.js +1 -19
  17. package/lib/commonjs/components/AskBuoyModal.js +1 -322
  18. package/lib/commonjs/components/ChangesBar.js +1 -211
  19. package/lib/commonjs/components/Composer.js +1 -175
  20. package/lib/commonjs/components/EmptyState.js +1 -154
  21. package/lib/commonjs/components/Markdown.js +1 -252
  22. package/lib/commonjs/components/MessageList.js +1 -648
  23. package/lib/commonjs/components/TypingDots.js +1 -63
  24. package/lib/commonjs/index.js +1 -205
  25. package/lib/commonjs/preset.js +1 -90
  26. package/lib/commonjs/store/askBuoyStore.js +1 -279
  27. package/lib/commonjs/store/useAskBuoy.js +1 -299
  28. package/lib/commonjs/sync/askBuoySyncAdapter.js +1 -119
  29. package/lib/commonjs/sync/askBuoySyncAdapter.test.js +1 -136
  30. package/lib/commonjs/sync/wire.js +1 -58
  31. package/lib/commonjs/types.js +1 -6
  32. package/lib/module/blocks/AskBlocks.js +1 -331
  33. package/lib/module/blocks/BlockRenderer.js +1 -245
  34. package/lib/module/blocks/ChromePrototypes.js +1 -503
  35. package/lib/module/blocks/DataBlocks.js +1 -532
  36. package/lib/module/blocks/ExtraBlocks.js +1 -1794
  37. package/lib/module/blocks/MediaBlocks.js +1 -135
  38. package/lib/module/blocks/ReceiptBlocks.js +1 -584
  39. package/lib/module/blocks/context.js +1 -35
  40. package/lib/module/blocks/icons.js +1 -91
  41. package/lib/module/blocks/index.js +1 -8
  42. package/lib/module/blocks/primitives.js +1 -301
  43. package/lib/module/blocks/primitivesIndex.js +1 -5
  44. package/lib/module/components/ApprovalCard.js +1 -135
  45. package/lib/module/components/AskBuoyHeader.js +1 -124
  46. package/lib/module/components/AskBuoyIcon.js +1 -8
  47. package/lib/module/components/AskBuoyModal.js +1 -317
  48. package/lib/module/components/ChangesBar.js +1 -206
  49. package/lib/module/components/Composer.js +1 -170
  50. package/lib/module/components/EmptyState.js +1 -149
  51. package/lib/module/components/Markdown.js +1 -246
  52. package/lib/module/components/MessageList.js +1 -642
  53. package/lib/module/components/TypingDots.js +1 -58
  54. package/lib/module/index.js +1 -29
  55. package/lib/module/preset.js +1 -73
  56. package/lib/module/store/askBuoyStore.js +1 -275
  57. package/lib/module/store/useAskBuoy.js +1 -293
  58. package/lib/module/sync/askBuoySyncAdapter.js +1 -114
  59. package/lib/module/sync/askBuoySyncAdapter.test.js +1 -135
  60. package/lib/module/sync/wire.js +1 -47
  61. package/lib/module/types.js +1 -4
  62. package/lib/typescript/preset.d.ts +1 -1
  63. package/package.json +8 -8
  64. package/lib/commonjs/blocks/AskBlocks.js.map +0 -1
  65. package/lib/commonjs/blocks/BlockRenderer.js.map +0 -1
  66. package/lib/commonjs/blocks/ChromePrototypes.js.map +0 -1
  67. package/lib/commonjs/blocks/DataBlocks.js.map +0 -1
  68. package/lib/commonjs/blocks/ExtraBlocks.js.map +0 -1
  69. package/lib/commonjs/blocks/MediaBlocks.js.map +0 -1
  70. package/lib/commonjs/blocks/ReceiptBlocks.js.map +0 -1
  71. package/lib/commonjs/blocks/context.js.map +0 -1
  72. package/lib/commonjs/blocks/icons.js.map +0 -1
  73. package/lib/commonjs/blocks/index.js.map +0 -1
  74. package/lib/commonjs/blocks/primitives.js.map +0 -1
  75. package/lib/commonjs/blocks/primitivesIndex.js.map +0 -1
  76. package/lib/commonjs/components/ApprovalCard.js.map +0 -1
  77. package/lib/commonjs/components/AskBuoyHeader.js.map +0 -1
  78. package/lib/commonjs/components/AskBuoyIcon.js.map +0 -1
  79. package/lib/commonjs/components/AskBuoyModal.js.map +0 -1
  80. package/lib/commonjs/components/ChangesBar.js.map +0 -1
  81. package/lib/commonjs/components/Composer.js.map +0 -1
  82. package/lib/commonjs/components/EmptyState.js.map +0 -1
  83. package/lib/commonjs/components/Markdown.js.map +0 -1
  84. package/lib/commonjs/components/MessageList.js.map +0 -1
  85. package/lib/commonjs/components/TypingDots.js.map +0 -1
  86. package/lib/commonjs/index.js.map +0 -1
  87. package/lib/commonjs/preset.js.map +0 -1
  88. package/lib/commonjs/store/askBuoyStore.js.map +0 -1
  89. package/lib/commonjs/store/useAskBuoy.js.map +0 -1
  90. package/lib/commonjs/sync/askBuoySyncAdapter.js.map +0 -1
  91. package/lib/commonjs/sync/askBuoySyncAdapter.test.js.map +0 -1
  92. package/lib/commonjs/sync/wire.js.map +0 -1
  93. package/lib/commonjs/types.js.map +0 -1
  94. package/lib/module/blocks/AskBlocks.js.map +0 -1
  95. package/lib/module/blocks/BlockRenderer.js.map +0 -1
  96. package/lib/module/blocks/ChromePrototypes.js.map +0 -1
  97. package/lib/module/blocks/DataBlocks.js.map +0 -1
  98. package/lib/module/blocks/ExtraBlocks.js.map +0 -1
  99. package/lib/module/blocks/MediaBlocks.js.map +0 -1
  100. package/lib/module/blocks/ReceiptBlocks.js.map +0 -1
  101. package/lib/module/blocks/context.js.map +0 -1
  102. package/lib/module/blocks/icons.js.map +0 -1
  103. package/lib/module/blocks/index.js.map +0 -1
  104. package/lib/module/blocks/primitives.js.map +0 -1
  105. package/lib/module/blocks/primitivesIndex.js.map +0 -1
  106. package/lib/module/components/ApprovalCard.js.map +0 -1
  107. package/lib/module/components/AskBuoyHeader.js.map +0 -1
  108. package/lib/module/components/AskBuoyIcon.js.map +0 -1
  109. package/lib/module/components/AskBuoyModal.js.map +0 -1
  110. package/lib/module/components/ChangesBar.js.map +0 -1
  111. package/lib/module/components/Composer.js.map +0 -1
  112. package/lib/module/components/EmptyState.js.map +0 -1
  113. package/lib/module/components/Markdown.js.map +0 -1
  114. package/lib/module/components/MessageList.js.map +0 -1
  115. package/lib/module/components/TypingDots.js.map +0 -1
  116. package/lib/module/index.js.map +0 -1
  117. package/lib/module/preset.js.map +0 -1
  118. package/lib/module/store/askBuoyStore.js.map +0 -1
  119. package/lib/module/store/useAskBuoy.js.map +0 -1
  120. package/lib/module/sync/askBuoySyncAdapter.js.map +0 -1
  121. package/lib/module/sync/askBuoySyncAdapter.test.js.map +0 -1
  122. package/lib/module/sync/wire.js.map +0 -1
  123. package/lib/module/types.js.map +0 -1
  124. package/lib/typescript/blocks/AskBlocks.d.ts.map +0 -1
  125. package/lib/typescript/blocks/BlockRenderer.d.ts.map +0 -1
  126. package/lib/typescript/blocks/ChromePrototypes.d.ts.map +0 -1
  127. package/lib/typescript/blocks/DataBlocks.d.ts.map +0 -1
  128. package/lib/typescript/blocks/ExtraBlocks.d.ts.map +0 -1
  129. package/lib/typescript/blocks/MediaBlocks.d.ts.map +0 -1
  130. package/lib/typescript/blocks/ReceiptBlocks.d.ts.map +0 -1
  131. package/lib/typescript/blocks/context.d.ts.map +0 -1
  132. package/lib/typescript/blocks/icons.d.ts.map +0 -1
  133. package/lib/typescript/blocks/index.d.ts.map +0 -1
  134. package/lib/typescript/blocks/primitives.d.ts.map +0 -1
  135. package/lib/typescript/blocks/primitivesIndex.d.ts.map +0 -1
  136. package/lib/typescript/components/ApprovalCard.d.ts.map +0 -1
  137. package/lib/typescript/components/AskBuoyHeader.d.ts.map +0 -1
  138. package/lib/typescript/components/AskBuoyIcon.d.ts.map +0 -1
  139. package/lib/typescript/components/AskBuoyModal.d.ts.map +0 -1
  140. package/lib/typescript/components/ChangesBar.d.ts.map +0 -1
  141. package/lib/typescript/components/Composer.d.ts.map +0 -1
  142. package/lib/typescript/components/EmptyState.d.ts.map +0 -1
  143. package/lib/typescript/components/Markdown.d.ts.map +0 -1
  144. package/lib/typescript/components/MessageList.d.ts.map +0 -1
  145. package/lib/typescript/components/TypingDots.d.ts.map +0 -1
  146. package/lib/typescript/index.d.ts.map +0 -1
  147. package/lib/typescript/preset.d.ts.map +0 -1
  148. package/lib/typescript/store/askBuoyStore.d.ts.map +0 -1
  149. package/lib/typescript/store/useAskBuoy.d.ts.map +0 -1
  150. package/lib/typescript/sync/askBuoySyncAdapter.d.ts.map +0 -1
  151. package/lib/typescript/sync/askBuoySyncAdapter.test.d.ts.map +0 -1
  152. package/lib/typescript/sync/wire.d.ts.map +0 -1
  153. package/lib/typescript/types.d.ts.map +0 -1
@@ -1,211 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.ChangesBar = ChangesBar;
7
- var _react = require("react");
8
- var _reactNative = require("react-native");
9
- var _sharedUi = require("@buoy-gg/shared-ui");
10
- var _agentCore = require("@buoy-gg/agent-core");
11
- var _jsxRuntime = require("react/jsx-runtime");
12
- /**
13
- * "The agent changed things" — the bar, and the list behind it.
14
- *
15
- * Ask Buoy mutates without asking, so this is what keeps the user in control:
16
- * if reality has been bent, you can never not know it. Same principle as the
17
- * impersonate and override banners.
18
- *
19
- * It counts REVERSIBLE and ONE-SHOT effects separately, which is the one place
20
- * this deliberately differs from the Scenarios banner. That one folds
21
- * transients into a single "N changes" total and then silently no-ops on them
22
- * at revert — a user who taps Undo, sees "4 changes", and finds three of them
23
- * still in place learns not to trust the bar. Better to say "1 undoable ·
24
- * 1 permanent" and be believed.
25
- */
26
-
27
- const EMPTY = [];
28
- function useLedgerEntries(ledger) {
29
- return (0, _react.useSyncExternalStore)(fn => ledger?.subscribe(fn) ?? (() => {}), () => ledger?.list() ?? EMPTY, () => ledger?.list() ?? EMPTY);
30
- }
31
- function ChangesBar({
32
- ledger,
33
- onUndoAll,
34
- expanded,
35
- onToggle
36
- }) {
37
- const entries = useLedgerEntries(ledger);
38
- const outstanding = entries.filter(e => !e.undoneAt);
39
- // Transients — navigation, taps — are one-shot ACTIONS, not changes. Counting
40
- // them here read "Changed this app · 9 permanent" after a read-only tour,
41
- // which is the bar lying in the alarming direction. They still appear in the
42
- // expanded panel's footnote, because honesty, but they raise no banner.
43
- const changes = outstanding.filter(e => e.effect.kind !== "transient");
44
- if (changes.length === 0) return null;
45
- const reversible = changes.filter(e => (0, _agentCore.isReversible)(e.effect));
46
- const permanent = changes.length - reversible.length;
47
- const transients = outstanding.length - changes.length;
48
- const Chevron = expanded ? _sharedUi.ChevronDown : _sharedUi.ChevronRight;
49
- const counts = [reversible.length > 0 ? `${reversible.length} undoable` : null, permanent > 0 ? `${permanent} permanent` : null].filter(Boolean).join(" · ");
50
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
51
- style: styles.wrap,
52
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Pressable, {
53
- testID: "buoy-ask-buoy-changes-bar",
54
- accessibilityRole: "button",
55
- accessibilityState: {
56
- expanded
57
- },
58
- onPress: onToggle,
59
- style: styles.bar,
60
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
61
- style: styles.dot
62
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
63
- style: styles.summary,
64
- numberOfLines: 1,
65
- children: "Changed this app"
66
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
67
- style: styles.counts,
68
- numberOfLines: 1,
69
- children: counts
70
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(Chevron, {
71
- size: 12,
72
- color: _sharedUi.night.color.textSecondary
73
- })]
74
- }), expanded && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
75
- style: styles.panel,
76
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.ScrollView, {
77
- style: styles.panelScroll,
78
- testID: "buoy-ask-buoy-changes-scroll",
79
- keyboardShouldPersistTaps: "handled",
80
- children: [changes.map(entry => {
81
- const oneOff = !(0, _agentCore.isReversible)(entry.effect);
82
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
83
- style: styles.row,
84
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
85
- style: styles.rowLabel,
86
- children: entry.effect.label
87
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
88
- style: [styles.rowTag, oneOff && styles.rowTagMuted],
89
- children: oneOff ? "Permanent" : "Undoable"
90
- })]
91
- }, entry.id);
92
- }), transients > 0 && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
93
- style: styles.row,
94
- children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
95
- style: [styles.rowLabel, styles.rowLabelMuted],
96
- children: ["Also did ", transients, " one-shot action", transients === 1 ? "" : "s", " (navigation, taps) \u2014 nothing to undo."]
97
- })
98
- })]
99
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
100
- style: styles.footer,
101
- children: [reversible.length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
102
- testID: "buoy-ask-buoy-undo-all",
103
- accessibilityRole: "button",
104
- onPress: onUndoAll,
105
- style: ({
106
- pressed
107
- }) => [styles.undo, pressed && styles.pressed],
108
- children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
109
- style: styles.undoText,
110
- children: ["Undo ", reversible.length, " change", reversible.length === 1 ? "" : "s"]
111
- })
112
- }), permanent > 0 && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
113
- style: styles.footnote,
114
- children: "Permanent changes can't be undone from here."
115
- })]
116
- })]
117
- })]
118
- });
119
- }
120
- const styles = _reactNative.StyleSheet.create({
121
- wrap: {
122
- borderBottomWidth: _reactNative.StyleSheet.hairlineWidth,
123
- borderBottomColor: _sharedUi.night.color.border,
124
- backgroundColor: _sharedUi.night.color.warningSoft
125
- },
126
- bar: {
127
- flexDirection: "row",
128
- alignItems: "center",
129
- gap: 8,
130
- paddingHorizontal: _sharedUi.night.gutter,
131
- paddingVertical: 10
132
- },
133
- dot: {
134
- width: 7,
135
- height: 7,
136
- borderRadius: 4,
137
- backgroundColor: _sharedUi.night.color.warning
138
- },
139
- summary: {
140
- color: _sharedUi.night.color.text,
141
- fontSize: _sharedUi.night.font.caption,
142
- fontWeight: "600"
143
- },
144
- counts: {
145
- flex: 1,
146
- color: _sharedUi.night.color.textSecondary,
147
- fontSize: _sharedUi.night.font.caption
148
- },
149
- panel: {
150
- paddingHorizontal: _sharedUi.night.gutter,
151
- paddingBottom: 12,
152
- gap: 10
153
- },
154
- panelScroll: {
155
- maxHeight: 180
156
- },
157
- row: {
158
- flexDirection: "row",
159
- alignItems: "flex-start",
160
- gap: 10,
161
- paddingVertical: 8,
162
- borderTopWidth: _reactNative.StyleSheet.hairlineWidth,
163
- borderTopColor: _sharedUi.night.color.separator
164
- },
165
- rowLabel: {
166
- flex: 1,
167
- color: _sharedUi.night.color.text,
168
- fontSize: _sharedUi.night.font.caption,
169
- lineHeight: 18
170
- },
171
- rowTag: {
172
- color: _sharedUi.night.color.accent,
173
- fontSize: _sharedUi.night.font.micro,
174
- fontWeight: "600",
175
- letterSpacing: 0.6,
176
- textTransform: "uppercase",
177
- paddingTop: 2
178
- },
179
- rowTagMuted: {
180
- color: _sharedUi.night.color.textTertiary
181
- },
182
- rowLabelMuted: {
183
- color: _sharedUi.night.color.textTertiary
184
- },
185
- footer: {
186
- flexDirection: "row",
187
- alignItems: "center",
188
- gap: 12,
189
- flexWrap: "wrap"
190
- },
191
- undo: {
192
- paddingHorizontal: 14,
193
- paddingVertical: 8,
194
- borderRadius: _sharedUi.night.radius.row,
195
- backgroundColor: _sharedUi.night.color.button
196
- },
197
- undoText: {
198
- color: _sharedUi.night.color.accent,
199
- fontSize: _sharedUi.night.font.caption,
200
- fontWeight: "600"
201
- },
202
- footnote: {
203
- flex: 1,
204
- color: _sharedUi.night.color.textTertiary,
205
- fontSize: _sharedUi.night.font.micro
206
- },
207
- pressed: {
208
- opacity: 0.7
209
- }
210
- });
211
- //# sourceMappingURL=ChangesBar.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ChangesBar=ChangesBar;var _react=require("react"),_reactNative=require("react-native"),_sharedUi=require("@buoy-gg/shared-ui"),_agentCore=require("@buoy-gg/agent-core"),_jsxRuntime=require("react/jsx-runtime");const EMPTY=[];function useLedgerEntries(e){return(0,_react.useSyncExternalStore)(t=>e?.subscribe(t)??(()=>{}),()=>e?.list()??EMPTY,()=>e?.list()??EMPTY)}function ChangesBar({ledger:e,onUndoAll:t,expanded:r,onToggle:i}){const n=useLedgerEntries(e).filter(e=>!e.undoneAt),s=n.filter(e=>"transient"!==e.effect.kind);if(0===s.length)return null;const o=s.filter(e=>(0,_agentCore.isReversible)(e.effect)),a=s.length-o.length,l=n.length-s.length,c=r?_sharedUi.ChevronDown:_sharedUi.ChevronRight,d=[o.length>0?`${o.length} undoable`:null,a>0?`${a} permanent`:null].filter(Boolean).join(" · ");return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.wrap,children:[(0,_jsxRuntime.jsxs)(_reactNative.Pressable,{testID:"buoy-ask-buoy-changes-bar",accessibilityRole:"button",accessibilityState:{expanded:r},onPress:i,style:styles.bar,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.dot}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.summary,numberOfLines:1,children:"Changed this app"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.counts,numberOfLines:1,children:d}),(0,_jsxRuntime.jsx)(c,{size:12,color:_sharedUi.night.color.textSecondary})]}),r&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.panel,children:[(0,_jsxRuntime.jsxs)(_reactNative.ScrollView,{style:styles.panelScroll,testID:"buoy-ask-buoy-changes-scroll",keyboardShouldPersistTaps:"handled",children:[s.map(e=>{const t=!(0,_agentCore.isReversible)(e.effect);return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.row,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.rowLabel,children:e.effect.label}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.rowTag,t&&styles.rowTagMuted],children:t?"Permanent":"Undoable"})]},e.id)}),l>0&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.row,children:(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:[styles.rowLabel,styles.rowLabelMuted],children:["Also did ",l," one-shot action",1===l?"":"s"," (navigation, taps) — nothing to undo."]})})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.footer,children:[o.length>0&&(0,_jsxRuntime.jsx)(_reactNative.Pressable,{testID:"buoy-ask-buoy-undo-all",accessibilityRole:"button",onPress:t,style:({pressed:e})=>[styles.undo,e&&styles.pressed],children:(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.undoText,children:["Undo ",o.length," change",1===o.length?"":"s"]})}),a>0&&(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.footnote,children:"Permanent changes can't be undone from here."})]})]})]})}const styles=_reactNative.StyleSheet.create({wrap:{borderBottomWidth:_reactNative.StyleSheet.hairlineWidth,borderBottomColor:_sharedUi.night.color.border,backgroundColor:_sharedUi.night.color.warningSoft},bar:{flexDirection:"row",alignItems:"center",gap:8,paddingHorizontal:_sharedUi.night.gutter,paddingVertical:10},dot:{width:7,height:7,borderRadius:4,backgroundColor:_sharedUi.night.color.warning},summary:{color:_sharedUi.night.color.text,fontSize:_sharedUi.night.font.caption,fontWeight:"600"},counts:{flex:1,color:_sharedUi.night.color.textSecondary,fontSize:_sharedUi.night.font.caption},panel:{paddingHorizontal:_sharedUi.night.gutter,paddingBottom:12,gap:10},panelScroll:{maxHeight:180},row:{flexDirection:"row",alignItems:"flex-start",gap:10,paddingVertical:8,borderTopWidth:_reactNative.StyleSheet.hairlineWidth,borderTopColor:_sharedUi.night.color.separator},rowLabel:{flex:1,color:_sharedUi.night.color.text,fontSize:_sharedUi.night.font.caption,lineHeight:18},rowTag:{color:_sharedUi.night.color.accent,fontSize:_sharedUi.night.font.micro,fontWeight:"600",letterSpacing:.6,textTransform:"uppercase",paddingTop:2},rowTagMuted:{color:_sharedUi.night.color.textTertiary},rowLabelMuted:{color:_sharedUi.night.color.textTertiary},footer:{flexDirection:"row",alignItems:"center",gap:12,flexWrap:"wrap"},undo:{paddingHorizontal:14,paddingVertical:8,borderRadius:_sharedUi.night.radius.row,backgroundColor:_sharedUi.night.color.button},undoText:{color:_sharedUi.night.color.accent,fontSize:_sharedUi.night.font.caption,fontWeight:"600"},footnote:{flex:1,color:_sharedUi.night.color.textTertiary,fontSize:_sharedUi.night.font.micro},pressed:{opacity:.7}});
@@ -1,175 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.Composer = Composer;
7
- var _react = require("react");
8
- var _reactNative = require("react-native");
9
- var _sharedUi = require("@buoy-gg/shared-ui");
10
- var _jsxRuntime = require("react/jsx-runtime");
11
- /**
12
- * The message box.
13
- *
14
- * This is the first keyboard-safe BOTTOM input in Buoy, and the reason none
15
- * existed before is that JsModal has no keyboard handling at all: the sheet is
16
- * `position:absolute; bottom:0` inside the app tree, not an RN `Modal`, so on
17
- * iOS the keyboard simply draws over it. Two other tools hit this and chose to
18
- * dodge it — NetworkNumberPrompt and StorageValueEditModal both say so in
19
- * comments and pin their inputs to the TOP of the screen. A chat cannot.
20
- *
21
- * What makes it work:
22
- * - `KeyboardAvoidingView` with `behavior="padding"`, iOS only. On Android
23
- * Expo's default `softwareKeyboardLayoutMode: "resize"` shrinks the window
24
- * and a bottom-anchored view rides up for free; adding padding there would
25
- * lift it twice.
26
- * - The parent list carries `keyboardShouldPersistTaps="handled"`. Without it
27
- * the first tap after typing only dismisses the keyboard and Send never
28
- * fires — a real shipped bug in Time Machine, and invisible to Detox because
29
- * `replaceText` opens no keyboard.
30
- * - `keyboardType="ascii-capable"`, because iOS Smart Punctuation rewrites
31
- * straight quotes as curly ones. That permanently broke the raw-JSON editor
32
- * in Storage, and a tester pasting a JSON blob here would hit the same wall.
33
- *
34
- * While the agent is working the send button becomes a STOP button — a
35
- * square, the universal glyph — rather than a spinner in a circle, which
36
- * looked like a disabled control and gave no hint it was tappable.
37
- */
38
-
39
- function Composer({
40
- onSend,
41
- onStop,
42
- busy,
43
- disabled,
44
- placeholder
45
- }) {
46
- const [text, setText] = (0, _react.useState)("");
47
- const submit = (0, _react.useCallback)(() => {
48
- const value = text.trim();
49
- if (!value) return;
50
- setText("");
51
- onSend(value);
52
- }, [text, onSend]);
53
- const canSend = text.trim().length > 0 && !busy && !disabled;
54
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
55
- style: styles.wrap,
56
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
57
- style: [styles.field, disabled && styles.fieldDisabled],
58
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
59
- testID: "buoy-ask-buoy-input",
60
- style: styles.input,
61
- value: text,
62
- onChangeText: setText,
63
- placeholder: placeholder ?? (disabled ? "Ask Buoy isn't set up yet" : "Ask, or tell it what to change…"),
64
- placeholderTextColor: _sharedUi.night.color.placeholder,
65
- multiline: true,
66
- editable: !disabled
67
- // Straight quotes only — see the header note.
68
- ,
69
- keyboardType: "ascii-capable",
70
- autoCorrect: true,
71
- autoCapitalize: "sentences"
72
- // Enter sends; Shift-Enter is not a thing on a phone keyboard, and a
73
- // multiline box with no submit affordance strands people.
74
- ,
75
- blurOnSubmit: false,
76
- onSubmitEditing: submit,
77
- returnKeyType: "send",
78
- maxLength: 4000
79
- })
80
- }), busy ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
81
- testID: "buoy-ask-buoy-stop",
82
- accessibilityRole: "button",
83
- accessibilityLabel: "Stop",
84
- onPress: onStop,
85
- style: ({
86
- pressed
87
- }) => [styles.button, styles.stop, pressed && styles.pressed],
88
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
89
- style: styles.stopGlyph
90
- })
91
- }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
92
- testID: "buoy-ask-buoy-send",
93
- accessibilityRole: "button",
94
- accessibilityLabel: "Send",
95
- disabled: !canSend,
96
- onPress: submit,
97
- style: ({
98
- pressed
99
- }) => [styles.button, canSend ? styles.sendOn : styles.sendOff, pressed && canSend && styles.pressed],
100
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
101
- style: [styles.sendGlyph, {
102
- color: canSend ? _sharedUi.night.color.onAccent : _sharedUi.night.color.textTertiary
103
- }],
104
- children: "\u2191"
105
- })
106
- })]
107
- });
108
- }
109
- const styles = _reactNative.StyleSheet.create({
110
- wrap: {
111
- flexDirection: "row",
112
- alignItems: "flex-end",
113
- gap: 8,
114
- paddingHorizontal: _sharedUi.night.gutter,
115
- paddingTop: 10,
116
- paddingBottom: 6,
117
- borderTopWidth: _reactNative.StyleSheet.hairlineWidth,
118
- borderTopColor: _sharedUi.night.color.border,
119
- // Opaque: messages scroll UNDER the composer, and a translucent bar over
120
- // moving text is unreadable.
121
- backgroundColor: _sharedUi.night.color.bg
122
- },
123
- field: {
124
- flex: 1,
125
- minHeight: 40,
126
- justifyContent: "center",
127
- borderRadius: 20,
128
- borderWidth: _reactNative.StyleSheet.hairlineWidth,
129
- borderColor: _sharedUi.night.color.border,
130
- backgroundColor: _sharedUi.night.color.surfaceElevated
131
- },
132
- fieldDisabled: {
133
- opacity: 0.6
134
- },
135
- input: {
136
- maxHeight: 120,
137
- paddingHorizontal: 16,
138
- paddingTop: _reactNative.Platform.OS === "ios" ? 10 : 6,
139
- paddingBottom: _reactNative.Platform.OS === "ios" ? 10 : 6,
140
- color: _sharedUi.night.color.text,
141
- fontSize: _sharedUi.night.font.row,
142
- lineHeight: 20
143
- },
144
- button: {
145
- width: 40,
146
- height: 40,
147
- borderRadius: 20,
148
- alignItems: "center",
149
- justifyContent: "center"
150
- },
151
- sendGlyph: {
152
- fontSize: 20,
153
- fontWeight: "700",
154
- lineHeight: 22
155
- },
156
- sendOn: {
157
- backgroundColor: _sharedUi.night.color.accent
158
- },
159
- sendOff: {
160
- backgroundColor: _sharedUi.night.color.fill
161
- },
162
- stop: {
163
- backgroundColor: _sharedUi.night.color.fillTertiary
164
- },
165
- stopGlyph: {
166
- width: 12,
167
- height: 12,
168
- borderRadius: 2,
169
- backgroundColor: _sharedUi.night.color.text
170
- },
171
- pressed: {
172
- opacity: 0.7
173
- }
174
- });
175
- //# sourceMappingURL=Composer.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.Composer=Composer;var _react=require("react"),_reactNative=require("react-native"),_sharedUi=require("@buoy-gg/shared-ui"),_jsxRuntime=require("react/jsx-runtime");function Composer({onSend:e,onStop:t,busy:i,disabled:r,placeholder:s}){const[o,a]=(0,_react.useState)(""),l=(0,_react.useCallback)(()=>{const t=o.trim();t&&(a(""),e(t))},[o,e]),n=o.trim().length>0&&!i&&!r;return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.wrap,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.field,r&&styles.fieldDisabled],children:(0,_jsxRuntime.jsx)(_reactNative.TextInput,{testID:"buoy-ask-buoy-input",style:styles.input,value:o,onChangeText:a,placeholder:s??(r?"Ask Buoy isn't set up yet":"Ask, or tell it what to change…"),placeholderTextColor:_sharedUi.night.color.placeholder,multiline:!0,editable:!r,keyboardType:"ascii-capable",autoCorrect:!0,autoCapitalize:"sentences",blurOnSubmit:!1,onSubmitEditing:l,returnKeyType:"send",maxLength:4e3})}),i?(0,_jsxRuntime.jsx)(_reactNative.Pressable,{testID:"buoy-ask-buoy-stop",accessibilityRole:"button",accessibilityLabel:"Stop",onPress:t,style:({pressed:e})=>[styles.button,styles.stop,e&&styles.pressed],children:(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.stopGlyph})}):(0,_jsxRuntime.jsx)(_reactNative.Pressable,{testID:"buoy-ask-buoy-send",accessibilityRole:"button",accessibilityLabel:"Send",disabled:!n,onPress:l,style:({pressed:e})=>[styles.button,n?styles.sendOn:styles.sendOff,e&&n&&styles.pressed],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.sendGlyph,{color:n?_sharedUi.night.color.onAccent:_sharedUi.night.color.textTertiary}],children:"↑"})})]})}const styles=_reactNative.StyleSheet.create({wrap:{flexDirection:"row",alignItems:"flex-end",gap:8,paddingHorizontal:_sharedUi.night.gutter,paddingTop:10,paddingBottom:6,borderTopWidth:_reactNative.StyleSheet.hairlineWidth,borderTopColor:_sharedUi.night.color.border,backgroundColor:_sharedUi.night.color.bg},field:{flex:1,minHeight:40,justifyContent:"center",borderRadius:20,borderWidth:_reactNative.StyleSheet.hairlineWidth,borderColor:_sharedUi.night.color.border,backgroundColor:_sharedUi.night.color.surfaceElevated},fieldDisabled:{opacity:.6},input:{maxHeight:120,paddingHorizontal:16,paddingTop:"ios"===_reactNative.Platform.OS?10:6,paddingBottom:"ios"===_reactNative.Platform.OS?10:6,color:_sharedUi.night.color.text,fontSize:_sharedUi.night.font.row,lineHeight:20},button:{width:40,height:40,borderRadius:20,alignItems:"center",justifyContent:"center"},sendGlyph:{fontSize:20,fontWeight:"700",lineHeight:22},sendOn:{backgroundColor:_sharedUi.night.color.accent},sendOff:{backgroundColor:_sharedUi.night.color.fill},stop:{backgroundColor:_sharedUi.night.color.fillTertiary},stopGlyph:{width:12,height:12,borderRadius:2,backgroundColor:_sharedUi.night.color.text},pressed:{opacity:.7}});
@@ -1,154 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.EmptyState = EmptyState;
7
- var _reactNative = require("react-native");
8
- var _sharedUi = require("@buoy-gg/shared-ui");
9
- var _jsxRuntime = require("react/jsx-runtime");
10
- /**
11
- * The first screen.
12
- *
13
- * Written for someone who has never used a devtool. The suggestions are not
14
- * decoration — they are the fastest way to teach a tester what kind of sentence
15
- * works here, and they are phrased as outcomes ("why is this screen empty?")
16
- * rather than as tool names, because the tools are the thing this feature
17
- * exists to hide.
18
- */
19
-
20
- const isRelease = typeof __DEV__ !== "undefined" && !__DEV__;
21
- const SUGGESTIONS = ["Why is this screen empty?", "What did the last few network calls return?", "Show me what's saved for this user", "Make the next request to this screen fail with a 500"];
22
- function EmptyState({
23
- configured,
24
- onPick
25
- }) {
26
- if (!configured) {
27
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
28
- style: styles.wrap,
29
- testID: "buoy-ask-buoy-unconfigured",
30
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
31
- style: styles.title,
32
- children: "Not set up yet"
33
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
34
- style: styles.body,
35
- children: ["Ask Buoy talks to your own company's AI endpoint \u2014 nothing goes to Buoy. A developer needs to add the ", /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
36
- style: styles.code,
37
- children: "askBuoy"
38
- }), " prop to", " ", /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
39
- style: styles.code,
40
- children: "<FloatingDevTools />"
41
- }), " with your team's endpoint and model."]
42
- })]
43
- });
44
- }
45
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
46
- style: styles.wrap,
47
- testID: "buoy-ask-buoy-empty",
48
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
49
- style: styles.title,
50
- children: "Ask about this app"
51
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
52
- style: styles.body,
53
- children: "Ask what the app is doing right now, or tell it to change something. Anything it changes shows up in a bar at the top, and you can undo it."
54
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
55
- style: styles.buildLine,
56
- testID: "buoy-ask-buoy-build-line",
57
- children: isRelease ? "Release build — reading, impersonation and navigation work; simulations (forcing server responses, driving the screen) need a dev build." : "Dev build — full simulation available."
58
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
59
- style: styles.group,
60
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightSectionLabel, {
61
- children: "Try asking"
62
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
63
- style: styles.card,
64
- children: SUGGESTIONS.map((s, i) => /*#__PURE__*/(0, _jsxRuntime.jsx)(Suggestion, {
65
- text: s,
66
- onPick: onPick,
67
- last: i === SUGGESTIONS.length - 1
68
- }, s))
69
- })]
70
- })]
71
- });
72
- }
73
- function Suggestion({
74
- text,
75
- onPick,
76
- last
77
- }) {
78
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Pressable, {
79
- testID: `buoy-ask-buoy-suggestion-${text.slice(0, 12)}`,
80
- accessibilityRole: "button",
81
- onPress: () => onPick(text),
82
- style: ({
83
- pressed
84
- }) => [styles.row, !last && styles.rowDivider, pressed && styles.pressed],
85
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
86
- style: styles.rowText,
87
- children: text
88
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ChevronRight, {
89
- size: 14,
90
- color: _sharedUi.night.color.textTertiary
91
- })]
92
- });
93
- }
94
- const styles = _reactNative.StyleSheet.create({
95
- wrap: {
96
- flex: 1,
97
- justifyContent: "center",
98
- paddingHorizontal: _sharedUi.night.gutter,
99
- paddingVertical: 24,
100
- gap: 8
101
- },
102
- title: {
103
- color: _sharedUi.night.color.text,
104
- fontSize: 22,
105
- fontWeight: "700",
106
- letterSpacing: -0.3
107
- },
108
- body: {
109
- color: _sharedUi.night.color.textSecondary,
110
- fontSize: _sharedUi.night.font.body,
111
- lineHeight: 20
112
- },
113
- code: {
114
- color: _sharedUi.night.color.text,
115
- fontFamily: "Menlo"
116
- },
117
- buildLine: {
118
- marginTop: 8,
119
- color: _sharedUi.night.color.textTertiary,
120
- fontSize: _sharedUi.night.font.micro,
121
- lineHeight: 15
122
- },
123
- group: {
124
- marginTop: _sharedUi.night.groupGap - 8
125
- },
126
- card: {
127
- borderRadius: _sharedUi.night.radius.card,
128
- borderWidth: _reactNative.StyleSheet.hairlineWidth,
129
- borderColor: _sharedUi.night.color.border,
130
- backgroundColor: _sharedUi.night.color.surface,
131
- overflow: "hidden"
132
- },
133
- row: {
134
- flexDirection: "row",
135
- alignItems: "center",
136
- gap: 10,
137
- paddingHorizontal: _sharedUi.night.rowPadH,
138
- paddingVertical: 13
139
- },
140
- rowDivider: {
141
- borderBottomWidth: _reactNative.StyleSheet.hairlineWidth,
142
- borderBottomColor: _sharedUi.night.color.separator
143
- },
144
- rowText: {
145
- flex: 1,
146
- color: _sharedUi.night.color.text,
147
- fontSize: _sharedUi.night.font.body,
148
- lineHeight: 19
149
- },
150
- pressed: {
151
- backgroundColor: _sharedUi.night.color.fill
152
- }
153
- });
154
- //# sourceMappingURL=EmptyState.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.EmptyState=EmptyState;var _reactNative=require("react-native"),_sharedUi=require("@buoy-gg/shared-ui"),_jsxRuntime=require("react/jsx-runtime");const isRelease="undefined"!=typeof __DEV__&&!__DEV__,SUGGESTIONS=["Why is this screen empty?","What did the last few network calls return?","Show me what's saved for this user","Make the next request to this screen fail with a 500"];function EmptyState({configured:e,onPick:t}){return e?(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.wrap,testID:"buoy-ask-buoy-empty",children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.title,children:"Ask about this app"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.body,children:"Ask what the app is doing right now, or tell it to change something. Anything it changes shows up in a bar at the top, and you can undo it."}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.buildLine,testID:"buoy-ask-buoy-build-line",children:isRelease?"Release build — reading, impersonation and navigation work; simulations (forcing server responses, driving the screen) need a dev build.":"Dev build — full simulation available."}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.group,children:[(0,_jsxRuntime.jsx)(_sharedUi.NightSectionLabel,{children:"Try asking"}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.card,children:SUGGESTIONS.map((e,i)=>(0,_jsxRuntime.jsx)(Suggestion,{text:e,onPick:t,last:i===SUGGESTIONS.length-1},e))})]})]}):(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.wrap,testID:"buoy-ask-buoy-unconfigured",children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.title,children:"Not set up yet"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.body,children:["Ask Buoy talks to your own company's AI endpoint — nothing goes to Buoy. A developer needs to add the ",(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.code,children:"askBuoy"})," prop to"," ",(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.code,children:"<FloatingDevTools />"})," with your team's endpoint and model."]})]})}function Suggestion({text:e,onPick:t,last:i}){return(0,_jsxRuntime.jsxs)(_reactNative.Pressable,{testID:`buoy-ask-buoy-suggestion-${e.slice(0,12)}`,accessibilityRole:"button",onPress:()=>t(e),style:({pressed:e})=>[styles.row,!i&&styles.rowDivider,e&&styles.pressed],children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.rowText,children:e}),(0,_jsxRuntime.jsx)(_sharedUi.ChevronRight,{size:14,color:_sharedUi.night.color.textTertiary})]})}const styles=_reactNative.StyleSheet.create({wrap:{flex:1,justifyContent:"center",paddingHorizontal:_sharedUi.night.gutter,paddingVertical:24,gap:8},title:{color:_sharedUi.night.color.text,fontSize:22,fontWeight:"700",letterSpacing:-.3},body:{color:_sharedUi.night.color.textSecondary,fontSize:_sharedUi.night.font.body,lineHeight:20},code:{color:_sharedUi.night.color.text,fontFamily:"Menlo"},buildLine:{marginTop:8,color:_sharedUi.night.color.textTertiary,fontSize:_sharedUi.night.font.micro,lineHeight:15},group:{marginTop:_sharedUi.night.groupGap-8},card:{borderRadius:_sharedUi.night.radius.card,borderWidth:_reactNative.StyleSheet.hairlineWidth,borderColor:_sharedUi.night.color.border,backgroundColor:_sharedUi.night.color.surface,overflow:"hidden"},row:{flexDirection:"row",alignItems:"center",gap:10,paddingHorizontal:_sharedUi.night.rowPadH,paddingVertical:13},rowDivider:{borderBottomWidth:_reactNative.StyleSheet.hairlineWidth,borderBottomColor:_sharedUi.night.color.separator},rowText:{flex:1,color:_sharedUi.night.color.text,fontSize:_sharedUi.night.font.body,lineHeight:19},pressed:{backgroundColor:_sharedUi.night.color.fill}});