@athenaintel/react 0.60.0 → 0.61.0

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 (137) hide show
  1. package/README.md +225 -2
  2. package/dist/agent-runtime/src/client-tool-bridge.cjs +20 -2
  3. package/dist/agent-runtime/src/client-tool-bridge.cjs.map +1 -1
  4. package/dist/agent-runtime/src/client-tool-bridge.d.ts +9 -4
  5. package/dist/agent-runtime/src/client-tool-bridge.js +20 -2
  6. package/dist/agent-runtime/src/client-tool-bridge.js.map +1 -1
  7. package/dist/agent-runtime/src/client-tools.cjs.map +1 -1
  8. package/dist/agent-runtime/src/client-tools.d.ts +9 -0
  9. package/dist/agent-runtime/src/client-tools.js.map +1 -1
  10. package/dist/agent-ui/AgentTarget.cjs +11 -0
  11. package/dist/agent-ui/AgentTarget.cjs.map +1 -0
  12. package/dist/agent-ui/AgentTarget.d.ts +17 -0
  13. package/dist/agent-ui/AgentTarget.js +11 -0
  14. package/dist/agent-ui/AgentTarget.js.map +1 -0
  15. package/dist/agent-ui/AgentUiLayer.cjs +387 -0
  16. package/dist/agent-ui/AgentUiLayer.cjs.map +1 -0
  17. package/dist/agent-ui/AgentUiLayer.d.ts +40 -0
  18. package/dist/agent-ui/AgentUiLayer.js +387 -0
  19. package/dist/agent-ui/AgentUiLayer.js.map +1 -0
  20. package/dist/agent-ui/contract.cjs +104 -0
  21. package/dist/agent-ui/contract.cjs.map +1 -0
  22. package/dist/agent-ui/contract.d.ts +113 -0
  23. package/dist/agent-ui/contract.js +104 -0
  24. package/dist/agent-ui/contract.js.map +1 -0
  25. package/dist/agent-ui/driver.cjs +335 -0
  26. package/dist/agent-ui/driver.cjs.map +1 -0
  27. package/dist/agent-ui/driver.d.ts +66 -0
  28. package/dist/agent-ui/driver.js +335 -0
  29. package/dist/agent-ui/driver.js.map +1 -0
  30. package/dist/agent-ui/index.cjs +33 -0
  31. package/dist/agent-ui/index.cjs.map +1 -0
  32. package/dist/agent-ui/index.d.ts +19 -0
  33. package/dist/agent-ui/index.js +33 -0
  34. package/dist/agent-ui/index.js.map +1 -0
  35. package/dist/agent-ui/pace.cjs +121 -0
  36. package/dist/agent-ui/pace.cjs.map +1 -0
  37. package/dist/agent-ui/pace.d.ts +66 -0
  38. package/dist/agent-ui/pace.js +121 -0
  39. package/dist/agent-ui/pace.js.map +1 -0
  40. package/dist/agent-ui/screen.cjs +471 -0
  41. package/dist/agent-ui/screen.cjs.map +1 -0
  42. package/dist/agent-ui/screen.d.ts +97 -0
  43. package/dist/agent-ui/screen.js +471 -0
  44. package/dist/agent-ui/screen.js.map +1 -0
  45. package/dist/agent-ui/secret-fields.cjs +50 -0
  46. package/dist/agent-ui/secret-fields.cjs.map +1 -0
  47. package/dist/agent-ui/secret-fields.d.ts +15 -0
  48. package/dist/agent-ui/secret-fields.js +50 -0
  49. package/dist/agent-ui/secret-fields.js.map +1 -0
  50. package/dist/agent-ui/stage.cjs +196 -0
  51. package/dist/agent-ui/stage.cjs.map +1 -0
  52. package/dist/agent-ui/stage.d.ts +110 -0
  53. package/dist/agent-ui/stage.js +196 -0
  54. package/dist/agent-ui/stage.js.map +1 -0
  55. package/dist/agent-ui/tools.cjs +448 -0
  56. package/dist/agent-ui/tools.cjs.map +1 -0
  57. package/dist/agent-ui/tools.d.ts +103 -0
  58. package/dist/agent-ui/tools.js +448 -0
  59. package/dist/agent-ui/tools.js.map +1 -0
  60. package/dist/agent-ui/use-agent-target.cjs +63 -0
  61. package/dist/agent-ui/use-agent-target.cjs.map +1 -0
  62. package/dist/agent-ui/use-agent-target.d.ts +27 -0
  63. package/dist/agent-ui/use-agent-target.js +63 -0
  64. package/dist/agent-ui/use-agent-target.js.map +1 -0
  65. package/dist/agent-ui/use-agent-ui.cjs +15 -0
  66. package/dist/agent-ui/use-agent-ui.cjs.map +1 -0
  67. package/dist/agent-ui/use-agent-ui.d.ts +24 -0
  68. package/dist/agent-ui/use-agent-ui.js +15 -0
  69. package/dist/agent-ui/use-agent-ui.js.map +1 -0
  70. package/dist/chat/AthenaChat.cjs +19 -4
  71. package/dist/chat/AthenaChat.cjs.map +1 -1
  72. package/dist/chat/AthenaChat.d.ts +13 -0
  73. package/dist/chat/AthenaChat.js +19 -4
  74. package/dist/chat/AthenaChat.js.map +1 -1
  75. package/dist/chat/StatewireClientToolBridge.cjs +74 -1
  76. package/dist/chat/StatewireClientToolBridge.cjs.map +1 -1
  77. package/dist/chat/StatewireClientToolBridge.d.ts +16 -1
  78. package/dist/chat/StatewireClientToolBridge.js +75 -2
  79. package/dist/chat/StatewireClientToolBridge.js.map +1 -1
  80. package/dist/chat/StatewireClientToolConsentCard.cjs +66 -0
  81. package/dist/chat/StatewireClientToolConsentCard.cjs.map +1 -0
  82. package/dist/chat/StatewireClientToolConsentCard.d.ts +25 -0
  83. package/dist/chat/StatewireClientToolConsentCard.js +66 -0
  84. package/dist/chat/StatewireClientToolConsentCard.js.map +1 -0
  85. package/dist/chat/chat-voice-controls.cjs +5 -2
  86. package/dist/chat/chat-voice-controls.cjs.map +1 -1
  87. package/dist/chat/chat-voice-controls.d.ts +6 -1
  88. package/dist/chat/chat-voice-controls.js +6 -3
  89. package/dist/chat/chat-voice-controls.js.map +1 -1
  90. package/dist/chat/client-tool-write-consent.cjs +122 -0
  91. package/dist/chat/client-tool-write-consent.cjs.map +1 -0
  92. package/dist/chat/client-tool-write-consent.d.ts +79 -0
  93. package/dist/chat/client-tool-write-consent.js +122 -0
  94. package/dist/chat/client-tool-write-consent.js.map +1 -0
  95. package/dist/chat/statewire-client-tools.cjs +30 -5
  96. package/dist/chat/statewire-client-tools.cjs.map +1 -1
  97. package/dist/chat/statewire-client-tools.d.ts +34 -2
  98. package/dist/chat/statewire-client-tools.js +30 -5
  99. package/dist/chat/statewire-client-tools.js.map +1 -1
  100. package/dist/chat-ui/mentions/suggestions/data/sources/asset-type-icons.cjs +13 -0
  101. package/dist/chat-ui/mentions/suggestions/data/sources/asset-type-icons.cjs.map +1 -1
  102. package/dist/chat-ui/mentions/suggestions/data/sources/asset-type-icons.d.ts +12 -0
  103. package/dist/chat-ui/mentions/suggestions/data/sources/asset-type-icons.js +13 -0
  104. package/dist/chat-ui/mentions/suggestions/data/sources/asset-type-icons.js.map +1 -1
  105. package/dist/chat-ui/mentions/suggestions/data/sources/index.cjs +2 -1
  106. package/dist/chat-ui/mentions/suggestions/data/sources/index.cjs.map +1 -1
  107. package/dist/chat-ui/mentions/suggestions/data/sources/index.js +3 -2
  108. package/dist/chat-ui/mentions/suggestions/data/sources/index.js.map +1 -1
  109. package/dist/chat-ui/mentions/use-asset-icon-app-url.cjs +2 -1
  110. package/dist/chat-ui/mentions/use-asset-icon-app-url.cjs.map +1 -1
  111. package/dist/chat-ui/mentions/use-asset-icon-app-url.d.ts +2 -1
  112. package/dist/chat-ui/mentions/use-asset-icon-app-url.js +2 -1
  113. package/dist/chat-ui/mentions/use-asset-icon-app-url.js.map +1 -1
  114. package/dist/chat-ui/messages/message-components.cjs +1 -1
  115. package/dist/chat-ui/messages/message-components.cjs.map +1 -1
  116. package/dist/chat-ui/messages/message-components.d.ts +2 -2
  117. package/dist/chat-ui/messages/message-components.js +1 -1
  118. package/dist/chat-ui/messages/message-components.js.map +1 -1
  119. package/dist/chat-ui/statewire.cjs +4 -0
  120. package/dist/chat-ui/statewire.cjs.map +1 -1
  121. package/dist/chat-ui/statewire.d.ts +2 -0
  122. package/dist/chat-ui/statewire.js +4 -0
  123. package/dist/chat-ui/statewire.js.map +1 -1
  124. package/dist/index.cjs +12 -0
  125. package/dist/index.cjs.map +1 -1
  126. package/dist/index.d.ts +12 -2
  127. package/dist/index.js +13 -1
  128. package/dist/index.js.map +1 -1
  129. package/dist/provider/AthenaProvider.cjs +59 -11
  130. package/dist/provider/AthenaProvider.cjs.map +1 -1
  131. package/dist/provider/AthenaProvider.d.ts +25 -1
  132. package/dist/provider/AthenaProvider.js +55 -7
  133. package/dist/provider/AthenaProvider.js.map +1 -1
  134. package/dist/react/package.json.cjs +1 -1
  135. package/dist/react/package.json.js +1 -1
  136. package/dist/styles.css +1 -1
  137. package/package.json +6 -1
@@ -0,0 +1,387 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const lucideReact = require("lucide-react");
5
+ const require$$0 = require("react");
6
+ const reactDom = require("react-dom");
7
+ const lib_ownerDocument = require("../lib/owner-document.cjs");
8
+ const themeStyleContext = require("../provider/theme-style-context.cjs");
9
+ const contract = require("./contract.cjs");
10
+ const cnfast = require("cnfast");
11
+ const MARK_INSET_PX = 4;
12
+ const CARD_GAP_PX = 10;
13
+ const CARD_WIDTH_PX = 320;
14
+ const CARD_ROOM_PX = 150;
15
+ const EDGE_PX = 8;
16
+ function useElementBox(element) {
17
+ const [box, setBox] = require$$0.useState(null);
18
+ require$$0.useEffect(() => {
19
+ const view = element == null ? void 0 : element.ownerDocument.defaultView;
20
+ if (!element || !view) {
21
+ setBox(null);
22
+ return;
23
+ }
24
+ let frame = 0;
25
+ let last = "";
26
+ const read = () => {
27
+ const rect = element.isConnected ? element.getBoundingClientRect() : null;
28
+ const next = rect ? { top: rect.top, left: rect.left, width: rect.width, height: rect.height } : null;
29
+ const signature = next ? [next.top, next.left, next.width, next.height].map(Math.round).join(":") : "gone";
30
+ if (signature !== last) {
31
+ last = signature;
32
+ setBox(next);
33
+ }
34
+ frame = view.requestAnimationFrame(read);
35
+ };
36
+ read();
37
+ return () => view.cancelAnimationFrame(frame);
38
+ }, [element]);
39
+ return box;
40
+ }
41
+ function viewportOf(doc) {
42
+ const view = doc == null ? void 0 : doc.defaultView;
43
+ return { width: (view == null ? void 0 : view.innerWidth) ?? 1024, height: (view == null ? void 0 : view.innerHeight) ?? 768 };
44
+ }
45
+ function cardPosition({ box, viewport }) {
46
+ const width = Math.min(CARD_WIDTH_PX, viewport.width - EDGE_PX * 2);
47
+ if (!box) {
48
+ return { left: Math.max(EDGE_PX, (viewport.width - width) / 2), bottom: 24, width };
49
+ }
50
+ const left = Math.min(Math.max(box.left, EDGE_PX), Math.max(EDGE_PX, viewport.width - width - EDGE_PX));
51
+ const below = box.top + box.height + MARK_INSET_PX + CARD_GAP_PX;
52
+ if (below + CARD_ROOM_PX <= viewport.height || box.top < CARD_ROOM_PX) {
53
+ return { left, top: Math.min(below, Math.max(EDGE_PX, viewport.height - CARD_ROOM_PX)), width };
54
+ }
55
+ return { left, bottom: viewport.height - box.top + MARK_INSET_PX + CARD_GAP_PX, width };
56
+ }
57
+ const TONE_CLASS = {
58
+ point: "border-primary ring-primary/25",
59
+ act: "border-primary ring-primary/25 border-dashed",
60
+ ask: "border-amber-500 ring-amber-500/25"
61
+ };
62
+ function Mark({
63
+ box,
64
+ tone,
65
+ spotlight,
66
+ leaving,
67
+ className
68
+ }) {
69
+ return /* @__PURE__ */ jsxRuntime.jsx(
70
+ "div",
71
+ {
72
+ "data-testid": "agent-ui-mark",
73
+ "data-tone": tone,
74
+ className: cnfast.cn(
75
+ "pointer-events-none fixed rounded-lg border-2 ring-4 transition-opacity duration-500 motion-reduce:transition-none",
76
+ TONE_CLASS[tone],
77
+ spotlight && "shadow-[0_0_0_100vmax_rgb(0_0_0/0.45)]",
78
+ leaving ? "opacity-0" : "opacity-100",
79
+ className
80
+ ),
81
+ style: {
82
+ top: box.top - MARK_INSET_PX,
83
+ left: box.left - MARK_INSET_PX,
84
+ width: box.width + MARK_INSET_PX * 2,
85
+ height: box.height + MARK_INSET_PX * 2
86
+ }
87
+ }
88
+ );
89
+ }
90
+ function Card({
91
+ box,
92
+ viewport,
93
+ fit = false,
94
+ className,
95
+ children,
96
+ ...props
97
+ }) {
98
+ const { width, ...position } = cardPosition({ box, viewport });
99
+ return /* @__PURE__ */ jsxRuntime.jsx(
100
+ "div",
101
+ {
102
+ ...props,
103
+ className: cnfast.cn(
104
+ "pointer-events-auto fixed rounded-xl border border-border bg-popover px-3.5 py-3 text-popover-foreground text-sm shadow-lg",
105
+ className
106
+ ),
107
+ style: fit ? { ...position, maxWidth: width } : { ...position, width },
108
+ children
109
+ }
110
+ );
111
+ }
112
+ function Cursor({
113
+ box,
114
+ presses,
115
+ glideMs,
116
+ className
117
+ }) {
118
+ const x = box.left + box.width / 2;
119
+ const y = box.top + box.height / 2;
120
+ const [arrived, setArrived] = require$$0.useState(false);
121
+ require$$0.useEffect(() => {
122
+ const frame = requestAnimationFrame(() => setArrived(true));
123
+ return () => cancelAnimationFrame(frame);
124
+ }, []);
125
+ return /* @__PURE__ */ jsxRuntime.jsxs(
126
+ "div",
127
+ {
128
+ "data-testid": "agent-ui-cursor",
129
+ className: cnfast.cn("pointer-events-none fixed top-0 left-0 motion-reduce:transition-none", className),
130
+ style: {
131
+ transform: `translate(${arrived ? x : x + 48}px, ${arrived ? y : y + 48}px)`,
132
+ transitionProperty: "transform",
133
+ transitionTimingFunction: "ease-out",
134
+ transitionDuration: `${glideMs}ms`
135
+ },
136
+ children: [
137
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MousePointer2Icon, { className: "size-5 fill-primary text-primary-foreground drop-shadow" }),
138
+ presses > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
139
+ "span",
140
+ {
141
+ "data-testid": "agent-ui-press",
142
+ className: "-top-2 -left-2 absolute size-6 animate-ping rounded-full bg-primary/50 [animation-iteration-count:1]"
143
+ },
144
+ presses
145
+ ) : null
146
+ ]
147
+ }
148
+ );
149
+ }
150
+ function TourCard({
151
+ tour,
152
+ stage,
153
+ box,
154
+ viewport,
155
+ className
156
+ }) {
157
+ const step = tour.steps[tour.index];
158
+ const last = tour.index >= tour.steps.length - 1;
159
+ const progressRef = require$$0.useRef(null);
160
+ const advancing = tour.playing && !tour.searching;
161
+ const durationMs = (step == null ? void 0 : step.durationMs) ?? 0;
162
+ require$$0.useEffect(() => {
163
+ const bar = progressRef.current;
164
+ if (!bar || typeof bar.animate !== "function") return;
165
+ if (!advancing) return;
166
+ const animation = bar.animate([{ width: "0%" }, { width: "100%" }], {
167
+ duration: durationMs,
168
+ fill: "forwards",
169
+ easing: "linear"
170
+ });
171
+ return () => animation.cancel();
172
+ }, [advancing, durationMs, tour.index]);
173
+ if (!step) return null;
174
+ return /* @__PURE__ */ jsxRuntime.jsxs(
175
+ Card,
176
+ {
177
+ box,
178
+ viewport,
179
+ className,
180
+ role: "dialog",
181
+ "aria-label": tour.title ?? "Walkthrough",
182
+ "data-testid": "agent-ui-tour",
183
+ children: [
184
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3", children: [
185
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "min-w-0 truncate text-muted-foreground text-xs", children: [
186
+ tour.title ? `${tour.title} · ` : "",
187
+ "Step ",
188
+ tour.index + 1,
189
+ " of ",
190
+ tour.steps.length
191
+ ] }),
192
+ /* @__PURE__ */ jsxRuntime.jsx(
193
+ "button",
194
+ {
195
+ type: "button",
196
+ "aria-label": "Close the walkthrough",
197
+ onClick: () => stage.endTour(),
198
+ className: "shrink-0 rounded-md p-1 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
199
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, { className: "size-3.5" })
200
+ }
201
+ )
202
+ ] }),
203
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "break-words pt-1.5 leading-snug", "data-testid": "agent-ui-tour-text", children: step.text }),
204
+ !tour.searching && !tour.element ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "pt-1 text-muted-foreground text-xs", children: "This one is not on the page you have open." }) : null,
205
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2.5 h-0.5 overflow-hidden rounded-full bg-muted", children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: progressRef, className: "h-full w-0 bg-primary" }) }),
206
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 pt-2", children: [
207
+ /* @__PURE__ */ jsxRuntime.jsx(
208
+ "button",
209
+ {
210
+ type: "button",
211
+ "aria-label": "Previous step",
212
+ disabled: tour.index === 0,
213
+ onClick: () => stage.tourBack(),
214
+ className: "rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:opacity-40",
215
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeftIcon, { className: "size-4" })
216
+ }
217
+ ),
218
+ /* @__PURE__ */ jsxRuntime.jsx(
219
+ "button",
220
+ {
221
+ type: "button",
222
+ "aria-label": tour.playing ? "Pause the walkthrough" : "Play the walkthrough",
223
+ onClick: () => stage.tourTogglePlaying(),
224
+ className: "rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
225
+ children: tour.playing ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PauseIcon, { className: "size-4" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PlayIcon, { className: "size-4" })
226
+ }
227
+ ),
228
+ /* @__PURE__ */ jsxRuntime.jsxs(
229
+ "button",
230
+ {
231
+ type: "button",
232
+ onClick: () => stage.tourNext(),
233
+ className: "ml-auto flex items-center gap-1 rounded-md bg-primary px-2.5 py-1 font-medium text-primary-foreground text-xs transition-colors hover:bg-primary/90",
234
+ children: [
235
+ last ? "Done" : "Next",
236
+ last ? null : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRightIcon, { className: "size-3.5" })
237
+ ]
238
+ }
239
+ )
240
+ ] })
241
+ ]
242
+ }
243
+ );
244
+ }
245
+ function QuestionCard({
246
+ question,
247
+ stage,
248
+ box,
249
+ viewport,
250
+ className
251
+ }) {
252
+ return /* @__PURE__ */ jsxRuntime.jsxs(
253
+ Card,
254
+ {
255
+ box,
256
+ viewport,
257
+ className,
258
+ role: "alertdialog",
259
+ "aria-label": question.title,
260
+ "data-testid": "agent-ui-question",
261
+ children: [
262
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "break-words font-semibold leading-snug", children: question.title }),
263
+ question.body ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "break-words pt-1 text-muted-foreground leading-snug", children: question.body }) : null,
264
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2 pt-2.5", children: [
265
+ /* @__PURE__ */ jsxRuntime.jsx(
266
+ "button",
267
+ {
268
+ type: "button",
269
+ onClick: () => stage.answer(true),
270
+ className: "rounded-md bg-primary px-2.5 py-1 font-medium text-primary-foreground text-xs transition-colors hover:bg-primary/90",
271
+ children: question.allowLabel
272
+ }
273
+ ),
274
+ /* @__PURE__ */ jsxRuntime.jsx(
275
+ "button",
276
+ {
277
+ type: "button",
278
+ onClick: () => stage.answer(false),
279
+ className: "rounded-md border border-border px-2.5 py-1 font-medium text-xs transition-colors hover:bg-muted",
280
+ children: question.declineLabel
281
+ }
282
+ )
283
+ ] })
284
+ ]
285
+ }
286
+ );
287
+ }
288
+ function AgentUiLayer({ agentUi, classNames }) {
289
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
290
+ const { stage } = agentUi;
291
+ const state = require$$0.useSyncExternalStore(stage.subscribe, stage.getState, stage.getState);
292
+ const ownerDocument = lib_ownerDocument.useOwnerDocument();
293
+ const portalContainer = lib_ownerDocument.usePortalContainer();
294
+ const themeStyle = themeStyleContext.useAthenaThemeStyle();
295
+ const tourElement = ((_a = state.tour) == null ? void 0 : _a.element) ?? null;
296
+ const markedElement = state.tour ? tourElement : ((_b = state.mark) == null ? void 0 : _b.element) ?? null;
297
+ const markBox = useElementBox(markedElement);
298
+ const cursorBox = useElementBox(((_c = state.cursor) == null ? void 0 : _c.element) ?? null);
299
+ const questionBox = useElementBox(((_d = state.question) == null ? void 0 : _d.element) ?? null);
300
+ const showing = state.tour !== null || state.mark !== null;
301
+ require$$0.useEffect(() => {
302
+ if (!showing || !ownerDocument) return;
303
+ const onKeyDown = (event) => {
304
+ if (event.key !== "Escape") return;
305
+ stage.endTour();
306
+ stage.clearMark();
307
+ };
308
+ ownerDocument.addEventListener("keydown", onKeyDown);
309
+ return () => ownerDocument.removeEventListener("keydown", onKeyDown);
310
+ }, [ownerDocument, showing, stage]);
311
+ const container = portalContainer ?? (ownerDocument == null ? void 0 : ownerDocument.body);
312
+ if (!container) return null;
313
+ const idle = !state.mark && !state.cursor && !state.tour && !state.question;
314
+ if (idle) return null;
315
+ const viewport = viewportOf(ownerDocument);
316
+ const caption = state.tour ? null : ((_e = state.mark) == null ? void 0 : _e.caption) ?? null;
317
+ return reactDom.createPortal(
318
+ /* @__PURE__ */ jsxRuntime.jsxs(
319
+ "div",
320
+ {
321
+ ...{ [contract.AGENT_ATTR.layer]: "" },
322
+ className: "athena-sdk athena-sdk-chrome pointer-events-none fixed inset-0 z-[2147483000]",
323
+ style: themeStyle,
324
+ children: [
325
+ markBox && (state.tour || state.mark) ? /* @__PURE__ */ jsxRuntime.jsx(
326
+ Mark,
327
+ {
328
+ box: markBox,
329
+ tone: state.tour ? "point" : ((_f = state.mark) == null ? void 0 : _f.tone) ?? "point",
330
+ spotlight: state.tour ? false : ((_g = state.mark) == null ? void 0 : _g.spotlight) ?? false,
331
+ leaving: state.tour ? false : ((_h = state.mark) == null ? void 0 : _h.leaving) ?? false,
332
+ className: classNames == null ? void 0 : classNames.mark
333
+ }
334
+ ) : null,
335
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "aria-live": "polite", children: caption && markBox && !state.question ? /* @__PURE__ */ jsxRuntime.jsx(
336
+ Card,
337
+ {
338
+ box: markBox,
339
+ viewport,
340
+ fit: true,
341
+ className: cnfast.cn(
342
+ "pointer-events-none transition-opacity duration-500 motion-reduce:transition-none",
343
+ ((_i = state.mark) == null ? void 0 : _i.leaving) ? "opacity-0" : "opacity-100",
344
+ classNames == null ? void 0 : classNames.caption
345
+ ),
346
+ "data-testid": "agent-ui-caption",
347
+ children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "break-words leading-snug", children: caption })
348
+ }
349
+ ) : null }),
350
+ state.tour ? /* @__PURE__ */ jsxRuntime.jsx(
351
+ TourCard,
352
+ {
353
+ tour: state.tour,
354
+ stage,
355
+ box: markBox,
356
+ viewport,
357
+ className: classNames == null ? void 0 : classNames.tour
358
+ }
359
+ ) : null,
360
+ state.question ? /* @__PURE__ */ jsxRuntime.jsx(
361
+ QuestionCard,
362
+ {
363
+ question: state.question,
364
+ stage,
365
+ box: questionBox,
366
+ viewport,
367
+ className: classNames == null ? void 0 : classNames.question
368
+ }
369
+ ) : null,
370
+ state.cursor && cursorBox ? /* @__PURE__ */ jsxRuntime.jsx(
371
+ Cursor,
372
+ {
373
+ box: cursorBox,
374
+ presses: state.cursor.presses,
375
+ glideMs: agentUi.pace().cursorGlideMs,
376
+ className: classNames == null ? void 0 : classNames.cursor
377
+ }
378
+ ) : null
379
+ ]
380
+ }
381
+ ),
382
+ container
383
+ );
384
+ }
385
+ exports.AgentUiLayer = AgentUiLayer;
386
+ exports.cardPosition = cardPosition;
387
+ //# sourceMappingURL=AgentUiLayer.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AgentUiLayer.cjs","sources":["../../src/agent-ui/AgentUiLayer.tsx"],"sourcesContent":["'use client';\n\nimport {\n ChevronLeftIcon,\n ChevronRightIcon,\n MousePointer2Icon,\n PauseIcon,\n PlayIcon,\n XIcon,\n} from 'lucide-react';\nimport {\n type CSSProperties,\n type ReactNode,\n useEffect,\n useRef,\n useState,\n useSyncExternalStore,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { useOwnerDocument, usePortalContainer } from '../lib/owner-document';\nimport { cn } from '../lib/utils';\nimport { useAthenaThemeStyle } from '../provider/theme-style-context';\nimport { AGENT_ATTR } from './contract';\nimport type { AgentUiMarkTone, AgentUiQuestion, AgentUiStage, AgentUiTour } from './stage';\nimport type { AgentUi } from './tools';\n\n/*\n * The overlay: what the person sees of the agent on their page. A box around\n * the element it means, a note beside it, a cursor where it clicks, the\n * walkthrough's card and the question it asks before acting.\n *\n * It draws the stage and nothing else. Every piece is restyled through\n * `classNames`; a host that wants something else entirely reads\n * `agentUi.stage` and draws its own.\n */\n\nexport interface AgentUiLayerClassNames {\n /** The box around the element. */\n mark?: string;\n /** The note beside a marked element. */\n caption?: string;\n /** The agent's cursor. */\n cursor?: string;\n /** The walkthrough's card. */\n tour?: string;\n /** The question asked before acting. */\n question?: string;\n}\n\nexport interface AgentUiLayerProps {\n agentUi: AgentUi;\n classNames?: AgentUiLayerClassNames;\n}\n\ninterface Box {\n top: number;\n left: number;\n width: number;\n height: number;\n}\n\n/** Space between an element and the box drawn around it. */\nconst MARK_INSET_PX = 4;\n/** Space between the box and a card anchored to it. */\nconst CARD_GAP_PX = 10;\n/** A card's width, and the room a card needs below an element to sit there. */\nconst CARD_WIDTH_PX = 320;\nconst CARD_ROOM_PX = 150;\nconst EDGE_PX = 8;\n\n/** Follow an element's box frame by frame while it is shown: it rides scrolling and layout changes. */\nfunction useElementBox(element: Element | null): Box | null {\n const [box, setBox] = useState<Box | null>(null);\n useEffect(() => {\n const view = element?.ownerDocument.defaultView;\n if (!element || !view) {\n setBox(null);\n return;\n }\n let frame = 0;\n let last = '';\n const read = () => {\n const rect = element.isConnected ? element.getBoundingClientRect() : null;\n const next = rect ? { top: rect.top, left: rect.left, width: rect.width, height: rect.height } : null;\n const signature = next\n ? [next.top, next.left, next.width, next.height].map(Math.round).join(':')\n : 'gone';\n if (signature !== last) {\n last = signature;\n setBox(next);\n }\n frame = view.requestAnimationFrame(read);\n };\n read();\n return () => view.cancelAnimationFrame(frame);\n }, [element]);\n return box;\n}\n\ninterface Viewport {\n width: number;\n height: number;\n}\n\nfunction viewportOf(doc: Document | null): Viewport {\n const view = doc?.defaultView;\n return { width: view?.innerWidth ?? 1024, height: view?.innerHeight ?? 768 };\n}\n\n/** Where a card anchored to an element sits: under it when there is room, else over it; at the bottom of the page without one. */\nexport function cardPosition({ box, viewport }: { box: Box | null; viewport: Viewport }): CSSProperties {\n const width = Math.min(CARD_WIDTH_PX, viewport.width - EDGE_PX * 2);\n if (!box) {\n return { left: Math.max(EDGE_PX, (viewport.width - width) / 2), bottom: 24, width };\n }\n const left = Math.min(Math.max(box.left, EDGE_PX), Math.max(EDGE_PX, viewport.width - width - EDGE_PX));\n const below = box.top + box.height + MARK_INSET_PX + CARD_GAP_PX;\n if (below + CARD_ROOM_PX <= viewport.height || box.top < CARD_ROOM_PX) {\n return { left, top: Math.min(below, Math.max(EDGE_PX, viewport.height - CARD_ROOM_PX)), width };\n }\n return { left, bottom: viewport.height - box.top + MARK_INSET_PX + CARD_GAP_PX, width };\n}\n\nconst TONE_CLASS: Record<AgentUiMarkTone, string> = {\n point: 'border-primary ring-primary/25',\n act: 'border-primary ring-primary/25 border-dashed',\n ask: 'border-amber-500 ring-amber-500/25',\n};\n\nfunction Mark({\n box,\n tone,\n spotlight,\n leaving,\n className,\n}: {\n box: Box;\n tone: AgentUiMarkTone;\n spotlight: boolean;\n leaving: boolean;\n className?: string;\n}) {\n return (\n <div\n data-testid=\"agent-ui-mark\"\n data-tone={tone}\n className={cn(\n 'pointer-events-none fixed rounded-lg border-2 ring-4 transition-opacity duration-500 motion-reduce:transition-none',\n TONE_CLASS[tone],\n spotlight && 'shadow-[0_0_0_100vmax_rgb(0_0_0/0.45)]',\n leaving ? 'opacity-0' : 'opacity-100',\n className,\n )}\n style={{\n top: box.top - MARK_INSET_PX,\n left: box.left - MARK_INSET_PX,\n width: box.width + MARK_INSET_PX * 2,\n height: box.height + MARK_INSET_PX * 2,\n }}\n />\n );\n}\n\nfunction Card({\n box,\n viewport,\n fit = false,\n className,\n children,\n ...props\n}: {\n box: Box | null;\n viewport: Viewport;\n /** As wide as its words need, up to a card's width (a note); otherwise a card's full width. */\n fit?: boolean;\n className?: string;\n children: ReactNode;\n role?: string;\n 'aria-label'?: string;\n 'data-testid'?: string;\n}) {\n const { width, ...position } = cardPosition({ box, viewport });\n return (\n <div\n {...props}\n className={cn(\n 'pointer-events-auto fixed rounded-xl border border-border bg-popover px-3.5 py-3 text-popover-foreground text-sm shadow-lg',\n className,\n )}\n style={fit ? { ...position, maxWidth: width } : { ...position, width }}\n >\n {children}\n </div>\n );\n}\n\nfunction Cursor({\n box,\n presses,\n glideMs,\n className,\n}: {\n box: Box;\n presses: number;\n glideMs: number;\n className?: string;\n}) {\n const x = box.left + box.width / 2;\n const y = box.top + box.height / 2;\n // The cursor starts a little off the element and glides onto it.\n const [arrived, setArrived] = useState(false);\n useEffect(() => {\n const frame = requestAnimationFrame(() => setArrived(true));\n return () => cancelAnimationFrame(frame);\n }, []);\n return (\n <div\n data-testid=\"agent-ui-cursor\"\n className={cn('pointer-events-none fixed top-0 left-0 motion-reduce:transition-none', className)}\n style={{\n transform: `translate(${arrived ? x : x + 48}px, ${arrived ? y : y + 48}px)`,\n transitionProperty: 'transform',\n transitionTimingFunction: 'ease-out',\n transitionDuration: `${glideMs}ms`,\n }}\n >\n <MousePointer2Icon className=\"size-5 fill-primary text-primary-foreground drop-shadow\" />\n {presses > 0 ? (\n <span\n key={presses}\n data-testid=\"agent-ui-press\"\n className=\"-top-2 -left-2 absolute size-6 animate-ping rounded-full bg-primary/50 [animation-iteration-count:1]\"\n />\n ) : null}\n </div>\n );\n}\n\nfunction TourCard({\n tour,\n stage,\n box,\n viewport,\n className,\n}: {\n tour: AgentUiTour;\n stage: AgentUiStage;\n box: Box | null;\n viewport: Viewport;\n className?: string;\n}) {\n const step = tour.steps[tour.index];\n const last = tour.index >= tour.steps.length - 1;\n const progressRef = useRef<HTMLDivElement>(null);\n const advancing = tour.playing && !tour.searching;\n const durationMs = step?.durationMs ?? 0;\n // The bar fills over the step's time, so the person sees it will move on by itself.\n // `tour.index` restarts it for a step of the same length.\n // biome-ignore lint/correctness/useExhaustiveDependencies: a new step restarts the bar\n useEffect(() => {\n const bar = progressRef.current;\n if (!bar || typeof bar.animate !== 'function') return;\n if (!advancing) return;\n const animation = bar.animate([{ width: '0%' }, { width: '100%' }], {\n duration: durationMs,\n fill: 'forwards',\n easing: 'linear',\n });\n return () => animation.cancel();\n }, [advancing, durationMs, tour.index]);\n if (!step) return null;\n return (\n <Card\n box={box}\n viewport={viewport}\n className={className}\n role=\"dialog\"\n aria-label={tour.title ?? 'Walkthrough'}\n data-testid=\"agent-ui-tour\"\n >\n <div className=\"flex items-center justify-between gap-3\">\n <p className=\"min-w-0 truncate text-muted-foreground text-xs\">\n {tour.title ? `${tour.title} · ` : ''}\n Step {tour.index + 1} of {tour.steps.length}\n </p>\n <button\n type=\"button\"\n aria-label=\"Close the walkthrough\"\n onClick={() => stage.endTour()}\n className=\"shrink-0 rounded-md p-1 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\"\n >\n <XIcon className=\"size-3.5\" />\n </button>\n </div>\n <p className=\"break-words pt-1.5 leading-snug\" data-testid=\"agent-ui-tour-text\">\n {step.text}\n </p>\n {!tour.searching && !tour.element ? (\n <p className=\"pt-1 text-muted-foreground text-xs\">This one is not on the page you have open.</p>\n ) : null}\n <div className=\"mt-2.5 h-0.5 overflow-hidden rounded-full bg-muted\">\n <div ref={progressRef} className=\"h-full w-0 bg-primary\" />\n </div>\n <div className=\"flex items-center gap-1 pt-2\">\n <button\n type=\"button\"\n aria-label=\"Previous step\"\n disabled={tour.index === 0}\n onClick={() => stage.tourBack()}\n className=\"rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:opacity-40\"\n >\n <ChevronLeftIcon className=\"size-4\" />\n </button>\n <button\n type=\"button\"\n aria-label={tour.playing ? 'Pause the walkthrough' : 'Play the walkthrough'}\n onClick={() => stage.tourTogglePlaying()}\n className=\"rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\"\n >\n {tour.playing ? <PauseIcon className=\"size-4\" /> : <PlayIcon className=\"size-4\" />}\n </button>\n <button\n type=\"button\"\n onClick={() => stage.tourNext()}\n className=\"ml-auto flex items-center gap-1 rounded-md bg-primary px-2.5 py-1 font-medium text-primary-foreground text-xs transition-colors hover:bg-primary/90\"\n >\n {last ? 'Done' : 'Next'}\n {last ? null : <ChevronRightIcon className=\"size-3.5\" />}\n </button>\n </div>\n </Card>\n );\n}\n\nfunction QuestionCard({\n question,\n stage,\n box,\n viewport,\n className,\n}: {\n question: AgentUiQuestion;\n stage: AgentUiStage;\n box: Box | null;\n viewport: Viewport;\n className?: string;\n}) {\n return (\n <Card\n box={box}\n viewport={viewport}\n className={className}\n role=\"alertdialog\"\n aria-label={question.title}\n data-testid=\"agent-ui-question\"\n >\n <p className=\"break-words font-semibold leading-snug\">{question.title}</p>\n {question.body ? (\n <p className=\"break-words pt-1 text-muted-foreground leading-snug\">{question.body}</p>\n ) : null}\n <div className=\"flex flex-wrap items-center gap-2 pt-2.5\">\n <button\n type=\"button\"\n onClick={() => stage.answer(true)}\n className=\"rounded-md bg-primary px-2.5 py-1 font-medium text-primary-foreground text-xs transition-colors hover:bg-primary/90\"\n >\n {question.allowLabel}\n </button>\n <button\n type=\"button\"\n onClick={() => stage.answer(false)}\n className=\"rounded-md border border-border px-2.5 py-1 font-medium text-xs transition-colors hover:bg-muted\"\n >\n {question.declineLabel}\n </button>\n </div>\n </Card>\n );\n}\n\n/**\n * Draws the agent's stage over the page. Mount one per `AgentUi`, anywhere\n * under the provider; it portals to the document's body and takes no clicks\n * except on its own cards.\n */\nexport function AgentUiLayer({ agentUi, classNames }: AgentUiLayerProps) {\n const { stage } = agentUi;\n const state = useSyncExternalStore(stage.subscribe, stage.getState, stage.getState);\n const ownerDocument = useOwnerDocument();\n const portalContainer = usePortalContainer();\n const themeStyle = useAthenaThemeStyle();\n\n const tourElement = state.tour?.element ?? null;\n const markedElement = state.tour ? tourElement : (state.mark?.element ?? null);\n const markBox = useElementBox(markedElement);\n const cursorBox = useElementBox(state.cursor?.element ?? null);\n const questionBox = useElementBox(state.question?.element ?? null);\n\n // Escape closes what the agent is showing: the person's page is theirs.\n const showing = state.tour !== null || state.mark !== null;\n useEffect(() => {\n if (!showing || !ownerDocument) return;\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key !== 'Escape') return;\n stage.endTour();\n stage.clearMark();\n };\n ownerDocument.addEventListener('keydown', onKeyDown);\n return () => ownerDocument.removeEventListener('keydown', onKeyDown);\n }, [ownerDocument, showing, stage]);\n\n const container = portalContainer ?? ownerDocument?.body;\n if (!container) return null;\n const idle = !state.mark && !state.cursor && !state.tour && !state.question;\n if (idle) return null;\n const viewport = viewportOf(ownerDocument);\n const caption = state.tour ? null : (state.mark?.caption ?? null);\n\n return createPortal(\n <div\n {...{ [AGENT_ATTR.layer]: '' }}\n className=\"athena-sdk athena-sdk-chrome pointer-events-none fixed inset-0 z-[2147483000]\"\n style={themeStyle as CSSProperties | undefined}\n >\n {markBox && (state.tour || state.mark) ? (\n <Mark\n box={markBox}\n tone={state.tour ? 'point' : (state.mark?.tone ?? 'point')}\n spotlight={state.tour ? false : (state.mark?.spotlight ?? false)}\n leaving={state.tour ? false : (state.mark?.leaving ?? false)}\n className={classNames?.mark}\n />\n ) : null}\n {/* What the agent is doing, said aloud for a screen reader too. */}\n <div aria-live=\"polite\">\n {caption && markBox && !state.question ? (\n <Card\n box={markBox}\n viewport={viewport}\n fit\n className={cn(\n 'pointer-events-none transition-opacity duration-500 motion-reduce:transition-none',\n state.mark?.leaving ? 'opacity-0' : 'opacity-100',\n classNames?.caption,\n )}\n data-testid=\"agent-ui-caption\"\n >\n <p className=\"break-words leading-snug\">{caption}</p>\n </Card>\n ) : null}\n </div>\n {state.tour ? (\n <TourCard\n tour={state.tour}\n stage={stage}\n box={markBox}\n viewport={viewport}\n className={classNames?.tour}\n />\n ) : null}\n {state.question ? (\n <QuestionCard\n question={state.question}\n stage={stage}\n box={questionBox}\n viewport={viewport}\n className={classNames?.question}\n />\n ) : null}\n {state.cursor && cursorBox ? (\n <Cursor\n box={cursorBox}\n presses={state.cursor.presses}\n glideMs={agentUi.pace().cursorGlideMs}\n className={classNames?.cursor}\n />\n ) : null}\n </div>,\n container,\n );\n}\n"],"names":["useState","useEffect","jsx","cn","jsxs","MousePointer2Icon","useRef","XIcon","ChevronLeftIcon","PauseIcon","PlayIcon","ChevronRightIcon","useSyncExternalStore","useOwnerDocument","usePortalContainer","useAthenaThemeStyle","createPortal","AGENT_ATTR"],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import { type CSSProperties } from 'react';
2
+ import type { AgentUi } from './tools';
3
+ export interface AgentUiLayerClassNames {
4
+ /** The box around the element. */
5
+ mark?: string;
6
+ /** The note beside a marked element. */
7
+ caption?: string;
8
+ /** The agent's cursor. */
9
+ cursor?: string;
10
+ /** The walkthrough's card. */
11
+ tour?: string;
12
+ /** The question asked before acting. */
13
+ question?: string;
14
+ }
15
+ export interface AgentUiLayerProps {
16
+ agentUi: AgentUi;
17
+ classNames?: AgentUiLayerClassNames;
18
+ }
19
+ interface Box {
20
+ top: number;
21
+ left: number;
22
+ width: number;
23
+ height: number;
24
+ }
25
+ interface Viewport {
26
+ width: number;
27
+ height: number;
28
+ }
29
+ /** Where a card anchored to an element sits: under it when there is room, else over it; at the bottom of the page without one. */
30
+ export declare function cardPosition({ box, viewport }: {
31
+ box: Box | null;
32
+ viewport: Viewport;
33
+ }): CSSProperties;
34
+ /**
35
+ * Draws the agent's stage over the page. Mount one per `AgentUi`, anywhere
36
+ * under the provider; it portals to the document's body and takes no clicks
37
+ * except on its own cards.
38
+ */
39
+ export declare function AgentUiLayer({ agentUi, classNames }: AgentUiLayerProps): import("react").ReactPortal | null;
40
+ export {};