@tangle-network/ui 11.12.0 → 11.13.1

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 (276) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/_virtual/_rolldown/runtime.js +13 -0
  3. package/dist/auth/auth.d.ts +53 -0
  4. package/dist/{auth-DOETfnd9.js → auth/auth.js} +7 -37
  5. package/dist/auth/login-layout.d.ts +20 -0
  6. package/dist/auth/login-layout.js +36 -0
  7. package/dist/auth.d.ts +2 -1
  8. package/dist/auth.js +2 -1
  9. package/dist/chat/agent-timeline.d.ts +83 -0
  10. package/dist/chat/agent-timeline.js +236 -0
  11. package/dist/chat/chat-container.d.ts +51 -0
  12. package/dist/chat/chat-container.js +309 -0
  13. package/dist/chat/chat-message.d.ts +22 -0
  14. package/dist/chat/chat-message.js +38 -0
  15. package/dist/chat/message-list.d.ts +32 -0
  16. package/dist/chat/message-list.js +37 -0
  17. package/dist/chat/thinking-indicator.d.ts +6 -0
  18. package/dist/chat/thinking-indicator.js +38 -0
  19. package/dist/chat/user-message.d.ts +21 -0
  20. package/dist/chat/user-message.js +42 -0
  21. package/dist/chat.d.ts +6 -1
  22. package/dist/chat.js +6 -1
  23. package/dist/editor/document-editor-pane.d.ts +37 -0
  24. package/dist/editor/document-editor-pane.js +199 -0
  25. package/dist/editor/editor-lazy.js +37 -0
  26. package/dist/editor/editor-loading.js +21 -0
  27. package/dist/editor/editor-peers.d.ts +6 -0
  28. package/dist/editor/editor-peers.js +155 -0
  29. package/dist/editor/editor-provider.d.ts +97 -0
  30. package/dist/editor/editor-provider.js +253 -0
  31. package/dist/editor/editor-toolbar.d.ts +11 -0
  32. package/dist/editor/editor-toolbar.js +106 -0
  33. package/dist/editor/markdown-conversion.js +23 -0
  34. package/dist/editor/markdown-document-editor.js +103 -0
  35. package/dist/editor/tiptap-editor.d.ts +45 -0
  36. package/dist/editor/tiptap-editor.js +271 -0
  37. package/dist/editor/use-editor.d.ts +67 -0
  38. package/dist/editor/use-editor.js +158 -0
  39. package/dist/editor.d.ts +6 -119
  40. package/dist/editor.js +5 -1
  41. package/dist/files/file-artifact-pane.d.ts +47 -0
  42. package/dist/files/file-artifact-pane.js +114 -0
  43. package/dist/files/file-format.d.ts +51 -0
  44. package/dist/{file-format-BgXbr-Ib.js → files/file-format.js} +1 -1
  45. package/dist/files/file-preview.d.ts +27 -0
  46. package/dist/files/file-preview.js +359 -0
  47. package/dist/files/file-tabs.d.ts +19 -0
  48. package/dist/files/file-tabs.js +48 -0
  49. package/dist/files/file-tree.d.ts +31 -0
  50. package/dist/files/file-tree.js +135 -0
  51. package/dist/files/rich-file-tree.d.ts +62 -0
  52. package/dist/files/rich-file-tree.js +122 -0
  53. package/dist/files.d.ts +6 -1
  54. package/dist/files.js +6 -2
  55. package/dist/hooks/use-auth.d.ts +40 -0
  56. package/dist/hooks/use-auth.js +91 -0
  57. package/dist/hooks/use-auto-scroll.d.ts +11 -0
  58. package/dist/hooks/use-auto-scroll.js +48 -0
  59. package/dist/hooks/use-dropdown-menu.d.ts +12 -0
  60. package/dist/hooks/use-dropdown-menu.js +31 -0
  61. package/dist/hooks/use-live-time.d.ts +7 -0
  62. package/dist/hooks/use-live-time.js +22 -0
  63. package/dist/hooks/use-realtime-session.d.ts +32 -0
  64. package/dist/hooks/use-realtime-session.js +235 -0
  65. package/dist/hooks/use-run-collapse-state.d.ts +13 -0
  66. package/dist/hooks/use-run-collapse-state.js +24 -0
  67. package/dist/hooks/use-run-groups.d.ts +11 -0
  68. package/dist/hooks/use-run-groups.js +85 -0
  69. package/dist/hooks/use-sdk-session.d.ts +59 -0
  70. package/dist/hooks/use-sdk-session.js +322 -0
  71. package/dist/hooks/use-sse-stream.d.ts +124 -0
  72. package/dist/hooks/use-sse-stream.js +229 -0
  73. package/dist/hooks/use-tool-call-stream.d.ts +23 -0
  74. package/dist/hooks/use-tool-call-stream.js +75 -0
  75. package/dist/hooks.d.ts +11 -49
  76. package/dist/hooks.js +10 -110
  77. package/dist/index.d.ts +99 -25
  78. package/dist/index.js +86 -36
  79. package/dist/lib/focus.d.ts +55 -0
  80. package/dist/{focus-BcE_SHqz.js → lib/focus.js} +1 -1
  81. package/dist/lib/utils.d.ts +4 -0
  82. package/dist/{utils-C_uf36nf.js → lib/utils.js} +1 -1
  83. package/dist/{code-block-B9miUPht.d.ts → markdown/code-block.d.ts} +5 -6
  84. package/dist/{code-block-B36KVUSN.js → markdown/code-block.js} +60 -55
  85. package/dist/{markdown-C0atSabr.d.ts → markdown/markdown.d.ts} +4 -5
  86. package/dist/{markdown-Db08KAYF.js → markdown/markdown.js} +3 -3
  87. package/dist/markdown.d.ts +2 -2
  88. package/dist/markdown.js +2 -2
  89. package/dist/{openui-artifact-renderer-fkBQaoLO.d.ts → openui/openui-artifact-renderer.d.ts} +20 -21
  90. package/dist/{openui-artifact-renderer-DG_i2lOR.js → openui/openui-artifact-renderer.js} +9 -7
  91. package/dist/{schema-BpW9rSSG.js → openui/schema-compiled.js} +2 -354
  92. package/dist/{schema-DAstk-J4.d.ts → openui/schema-data.d.ts} +3 -24
  93. package/dist/openui/schema-data.js +206 -0
  94. package/dist/openui-schema.d.ts +22 -3
  95. package/dist/openui-schema.js +138 -1
  96. package/dist/openui.d.ts +3 -2
  97. package/dist/openui.js +3 -2
  98. package/dist/{artifact-pane-BL_DFWNl.d.ts → primitives/artifact-pane.d.ts} +3 -4
  99. package/dist/{artifact-pane-DMXT9a8U.js → primitives/artifact-pane.js} +2 -2
  100. package/dist/primitives/avatar.d.ts +8 -0
  101. package/dist/primitives/avatar.js +25 -0
  102. package/dist/primitives/badge.d.ts +22 -0
  103. package/dist/primitives/badge.js +47 -0
  104. package/dist/{button-yoIv77e2.d.ts → primitives/button.d.ts} +2 -2
  105. package/dist/primitives/button.js +113 -0
  106. package/dist/primitives/card.d.ts +18 -0
  107. package/dist/primitives/card.js +52 -0
  108. package/dist/primitives/code-block.d.ts +6 -0
  109. package/dist/primitives/code-block.js +13 -0
  110. package/dist/primitives/dialog.d.ts +23 -0
  111. package/dist/primitives/dialog.js +59 -0
  112. package/dist/primitives/drop-zone.d.ts +23 -0
  113. package/dist/primitives/drop-zone.js +104 -0
  114. package/dist/primitives/dropdown-menu.d.ts +29 -0
  115. package/dist/{dropdown-menu-BpcLa5vF.js → primitives/dropdown-menu.js} +2 -23
  116. package/dist/primitives/empty-state.d.ts +11 -0
  117. package/dist/primitives/empty-state.js +32 -0
  118. package/dist/primitives/heading.d.ts +23 -0
  119. package/dist/primitives/heading.js +38 -0
  120. package/dist/primitives/input.d.ts +23 -0
  121. package/dist/primitives/input.js +110 -0
  122. package/dist/primitives/label.d.ts +6 -0
  123. package/dist/primitives/label.js +16 -0
  124. package/dist/primitives/metric-strip.d.ts +48 -0
  125. package/dist/primitives/metric-strip.js +52 -0
  126. package/dist/primitives/page-header.d.ts +25 -0
  127. package/dist/primitives/page-header.js +47 -0
  128. package/dist/primitives/page-shell.d.ts +14 -0
  129. package/dist/primitives/page-shell.js +17 -0
  130. package/dist/primitives/progress.d.ts +9 -0
  131. package/dist/primitives/progress.js +29 -0
  132. package/dist/primitives/segmented-control.d.ts +40 -0
  133. package/dist/primitives/segmented-control.js +57 -0
  134. package/dist/primitives/select.d.ts +15 -0
  135. package/dist/primitives/select.js +74 -0
  136. package/dist/primitives/sidebar-drop-zone.d.ts +21 -0
  137. package/dist/primitives/sidebar-drop-zone.js +88 -0
  138. package/dist/primitives/skeleton.d.ts +10 -0
  139. package/dist/primitives/skeleton.js +50 -0
  140. package/dist/primitives/stat-card.d.ts +16 -0
  141. package/dist/primitives/stat-card.js +60 -0
  142. package/dist/primitives/status-pill.d.ts +44 -0
  143. package/dist/primitives/status-pill.js +119 -0
  144. package/dist/primitives/switch.d.ts +6 -0
  145. package/dist/primitives/switch.js +16 -0
  146. package/dist/primitives/table.d.ts +22 -0
  147. package/dist/primitives/table.js +63 -0
  148. package/dist/primitives/tabs.d.ts +13 -0
  149. package/dist/{tabs-BVHR6NkO.js → primitives/tabs.js} +3 -3
  150. package/dist/primitives/terminal-display.d.ts +25 -0
  151. package/dist/primitives/terminal-display.js +109 -0
  152. package/dist/primitives/text-shimmer.d.ts +16 -0
  153. package/dist/{text-shimmer-BUUo6I-g.js → primitives/text-shimmer.js} +2 -2
  154. package/dist/primitives/theme-toggle.d.ts +11 -0
  155. package/dist/primitives/theme-toggle.js +154 -0
  156. package/dist/primitives/toast.d.ts +29 -0
  157. package/dist/primitives/toast.js +142 -0
  158. package/dist/primitives/toolbar.d.ts +55 -0
  159. package/dist/primitives/toolbar.js +37 -0
  160. package/dist/primitives/upload-progress.d.ts +23 -0
  161. package/dist/primitives/upload-progress.js +72 -0
  162. package/dist/primitives.d.ts +35 -5
  163. package/dist/primitives.js +35 -9
  164. package/dist/{index-COgqsFAQ.d.ts → redaction/redacted-document.d.ts} +6 -7
  165. package/dist/{redaction-CGGB2ENG.js → redaction/redacted-document.js} +2 -2
  166. package/dist/redaction.d.ts +1 -1
  167. package/dist/redaction.js +1 -1
  168. package/dist/run/expandable-content.js +41 -0
  169. package/dist/run/expanded-tool-detail.d.ts +12 -0
  170. package/dist/run/expanded-tool-detail.js +163 -0
  171. package/dist/run/inline-thinking-item.d.ts +11 -0
  172. package/dist/run/inline-thinking-item.js +60 -0
  173. package/dist/run/inline-tool-item.d.ts +25 -0
  174. package/dist/run/inline-tool-item.js +63 -0
  175. package/dist/run/run-group.d.ts +26 -0
  176. package/dist/{run-group-BWGeesgs.js → run/run-group.js} +9 -60
  177. package/dist/run/run-item-primitives.d.ts +5 -0
  178. package/dist/{run-ZsIKPA6J.js → run/run-item-primitives.js} +2 -2
  179. package/dist/run/run-row-shell.d.ts +53 -0
  180. package/dist/run/run-row-shell.js +114 -0
  181. package/dist/{tool-call-feed-BeB1_4pX.d.ts → run/tool-call-feed.d.ts} +7 -12
  182. package/dist/{tool-call-feed-BpmMLpPX.js → run/tool-call-feed.js} +4 -4
  183. package/dist/run/tool-call-step.d.ts +5 -0
  184. package/dist/run/tool-call-step.js +82 -0
  185. package/dist/run.d.ts +8 -2
  186. package/dist/run.js +7 -4
  187. package/dist/sdk-hooks.d.ts +8 -1
  188. package/dist/sdk-hooks.js +8 -2
  189. package/dist/stores/active-sessions-store.d.ts +83 -0
  190. package/dist/{active-sessions-store-Gt1R0rFG.js → stores/active-sessions-store.js} +1 -1
  191. package/dist/stores/chat-store.d.ts +14 -0
  192. package/dist/stores/chat-store.js +33 -0
  193. package/dist/stores.d.ts +3 -16
  194. package/dist/stores.js +2 -33
  195. package/dist/tool-previews/command-preview.d.ts +11 -0
  196. package/dist/tool-previews/command-preview.js +91 -0
  197. package/dist/tool-previews/diff-preview.d.ts +7 -0
  198. package/dist/tool-previews/diff-preview.js +76 -0
  199. package/dist/tool-previews/glob-results-preview.d.ts +7 -0
  200. package/dist/tool-previews/glob-results-preview.js +53 -0
  201. package/dist/tool-previews/grep-results-preview.d.ts +7 -0
  202. package/dist/tool-previews/grep-results-preview.js +99 -0
  203. package/dist/tool-previews/preview-primitives.js +58 -0
  204. package/dist/tool-previews/question-preview.d.ts +7 -0
  205. package/dist/tool-previews/question-preview.js +63 -0
  206. package/dist/tool-previews/web-search-preview.d.ts +7 -0
  207. package/dist/tool-previews/web-search-preview.js +78 -0
  208. package/dist/tool-previews/write-file-preview.d.ts +11 -0
  209. package/dist/tool-previews/write-file-preview.js +52 -0
  210. package/dist/tool-previews.d.ts +7 -1
  211. package/dist/tool-previews.js +7 -1
  212. package/dist/{branding-26d5ARIr.d.ts → types/branding.d.ts} +2 -3
  213. package/dist/{message-vhUI0c5G.d.ts → types/message.d.ts} +2 -3
  214. package/dist/{parts-5mhy9yJ3.d.ts → types/parts.d.ts} +8 -9
  215. package/dist/{run-OyWmIDqu.d.ts → types/run.d.ts} +9 -10
  216. package/dist/{tool-display-DgmL5rIU.d.ts → types/tool-display.d.ts} +5 -6
  217. package/dist/types.d.ts +5 -5
  218. package/dist/utils/copy-text.d.ts +7 -0
  219. package/dist/{utils-Bl_CZ0Qp.js → utils/copy-text.js} +1 -11
  220. package/dist/utils/format.d.ts +22 -0
  221. package/dist/{format-DfcLWqMa.js → utils/format.js} +1 -1
  222. package/dist/utils/time-ago.d.ts +3 -0
  223. package/dist/utils/time-ago.js +11 -0
  224. package/dist/utils/tool-display.d.ts +16 -0
  225. package/dist/{tool-display-BAuAVa43.js → utils/tool-display.js} +1 -1
  226. package/dist/utils.d.ts +6 -1
  227. package/dist/utils.js +6 -5
  228. package/package.json +2 -2
  229. package/src/files/rich-file-tree.stories.tsx +1 -1
  230. package/src/files/rich-file-tree.tsx +12 -9
  231. package/src/markdown/code-block.test.tsx +80 -2
  232. package/src/markdown/code-block.tsx +76 -80
  233. package/src/primitives/button.stories.tsx +37 -1
  234. package/src/primitives/button.test.tsx +230 -0
  235. package/src/primitives/button.tsx +62 -14
  236. package/src/primitives/card-anatomy.stories.tsx +51 -0
  237. package/src/primitives/card.test.tsx +71 -0
  238. package/src/primitives/card.tsx +25 -13
  239. package/src/primitives/heading.stories.tsx +35 -0
  240. package/src/primitives/heading.test.tsx +56 -0
  241. package/src/primitives/heading.tsx +76 -0
  242. package/src/primitives/index.ts +8 -0
  243. package/src/primitives/input.stories.tsx +28 -0
  244. package/src/primitives/input.test.tsx +161 -0
  245. package/src/primitives/input.tsx +34 -28
  246. package/src/primitives/page-header.stories.tsx +51 -0
  247. package/src/primitives/page-header.test.tsx +48 -0
  248. package/src/primitives/page-header.tsx +35 -35
  249. package/src/primitives/page-shell.stories.tsx +89 -0
  250. package/src/primitives/page-shell.test.tsx +24 -0
  251. package/src/primitives/page-shell.tsx +26 -0
  252. package/src/primitives/table-wrapper.stories.tsx +54 -0
  253. package/src/primitives/table.test.tsx +72 -0
  254. package/src/primitives/table.tsx +33 -12
  255. package/src/primitives/theme-toggle.test.tsx +167 -0
  256. package/src/primitives/theme-toggle.tsx +111 -39
  257. package/dist/active-sessions-store-nl70ZnMC.d.ts +0 -84
  258. package/dist/button-C87nEe2R.js +0 -78
  259. package/dist/chat-DDvF2oGQ.js +0 -672
  260. package/dist/diff-preview-BcK3nRXb.js +0 -533
  261. package/dist/document-editor-pane-BilJfiCo.d.ts +0 -136
  262. package/dist/document-editor-pane-POsq5Q0o.js +0 -1279
  263. package/dist/files-hywocVZz.js +0 -753
  264. package/dist/index-2UntyjBb.d.ts +0 -52
  265. package/dist/index-BgUHilZm.d.ts +0 -108
  266. package/dist/index-CJ8wRfiC.d.ts +0 -236
  267. package/dist/index-CPDET_s1.d.ts +0 -549
  268. package/dist/index-Cg6gYAqh.d.ts +0 -73
  269. package/dist/index-Cs7j8V7l.d.ts +0 -203
  270. package/dist/index-DjKxO357.d.ts +0 -128
  271. package/dist/primitives-Bx59fT-U.js +0 -1239
  272. package/dist/table-Bss73DhB.js +0 -146
  273. package/dist/tool-call-step-DNebqhmX.js +0 -434
  274. package/dist/use-auto-scroll-C5Pjeqon.js +0 -153
  275. package/dist/use-sse-stream-DjqRuDft.js +0 -884
  276. package/dist/use-sse-stream-Dm6R5YWz.d.ts +0 -282
@@ -1,672 +0,0 @@
1
- import { i as focusRing } from "./focus-BcE_SHqz.js";
2
- import { t as cn } from "./utils-C_uf36nf.js";
3
- import { r as getToolDisplayMetadata } from "./tool-display-BAuAVa43.js";
4
- import { n as useRunCollapseState, r as useRunGroups, t as useAutoScroll } from "./use-auto-scroll-C5Pjeqon.js";
5
- import { n as ToolCallStep, t as ToolCallGroup } from "./tool-call-step-DNebqhmX.js";
6
- import { t as Markdown } from "./markdown-Db08KAYF.js";
7
- import { n as InlineThinkingItem, t as RunGroup } from "./run-group-BWGeesgs.js";
8
- import { t as OpenUIArtifactRenderer } from "./openui-artifact-renderer-DG_i2lOR.js";
9
- import { memo, useEffect, useMemo, useRef, useState } from "react";
10
- import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
11
- import { AlertTriangle, ArrowDown, CheckCircle2, CircleDot, FileText, Info } from "lucide-react";
12
- //#region src/chat/user-message.tsx
13
- function formatTime$1(date) {
14
- return date.toLocaleTimeString(void 0, {
15
- hour: "numeric",
16
- minute: "2-digit"
17
- });
18
- }
19
- /**
20
- * The single user message bubble uses inverse theme colors. The timestamp sits
21
- * beside the bubble and appears on hover, so it costs no height. Used by both
22
- * the run/message list (session-model `parts`) and AgentTimeline (direct
23
- * `content`/`timestamp`).
24
- */
25
- const UserMessage = memo(({ message: _message, parts, content, timestamp, actions }) => {
26
- const text = content ?? (parts ?? []).filter((p) => p.type === "text").map((p) => p.text).join("\n");
27
- if (!text.trim()) return null;
28
- return /* @__PURE__ */ jsx("div", {
29
- className: "flex justify-end",
30
- children: /* @__PURE__ */ jsxs("div", {
31
- className: "group flex min-w-0 max-w-[78%] flex-col items-end gap-2",
32
- children: [/* @__PURE__ */ jsxs("div", {
33
- className: "relative w-full min-w-0 rounded-2xl bg-foreground px-4 py-3 text-background",
34
- children: [timestamp ? /* @__PURE__ */ jsx("span", {
35
- "data-user-message-time": "",
36
- className: "pointer-events-none absolute right-full top-1/2 mr-3 -translate-y-1/2 whitespace-nowrap text-[var(--font-size-xs)] text-muted-foreground opacity-0 transition-opacity group-hover:opacity-100",
37
- children: formatTime$1(timestamp)
38
- }) : null, /* @__PURE__ */ jsx("div", {
39
- className: "break-words whitespace-pre-wrap text-[var(--font-size-base)] leading-[1.5]",
40
- children: text
41
- })]
42
- }), actions ? /* @__PURE__ */ jsx("div", {
43
- className: "flex flex-wrap items-center justify-end gap-1.5 text-xs text-muted-foreground",
44
- children: actions
45
- }) : null]
46
- })
47
- });
48
- });
49
- UserMessage.displayName = "UserMessage";
50
- //#endregion
51
- //#region src/chat/message-list.tsx
52
- /**
53
- * Maps GroupedMessage[] to UserMessage and RunGroup components.
54
- * This is the main render list for the chat view.
55
- */
56
- const MessageList = memo(({ groups, partMap, isCollapsed, onToggleCollapse, branding, renderToolDetail, renderRunActions, renderUserMessageActions, renderToolActions }) => {
57
- return /* @__PURE__ */ jsx("div", {
58
- className: "space-y-4",
59
- children: groups.map((group) => {
60
- if (group.type === "user") {
61
- const messageParts = partMap[group.message.id] ?? [];
62
- return /* @__PURE__ */ jsx(UserMessage, {
63
- message: group.message,
64
- parts: messageParts,
65
- actions: renderUserMessageActions?.(group.message, messageParts)
66
- }, group.message.id);
67
- }
68
- return /* @__PURE__ */ jsx(RunGroup, {
69
- run: group.run,
70
- partMap,
71
- collapsed: isCollapsed(group.run.id),
72
- onToggle: () => onToggleCollapse(group.run.id),
73
- branding,
74
- renderToolDetail,
75
- headerActions: renderRunActions?.(group.run),
76
- renderToolActions
77
- }, group.run.id);
78
- })
79
- });
80
- });
81
- MessageList.displayName = "MessageList";
82
- //#endregion
83
- //#region src/chat/thinking-indicator.tsx
84
- function ThinkingIndicator({ className }) {
85
- const [elapsed, setElapsed] = useState(0);
86
- useEffect(() => {
87
- const interval = window.setInterval(() => setElapsed((current) => current + 1), 1e3);
88
- return () => window.clearInterval(interval);
89
- }, []);
90
- return /* @__PURE__ */ jsxs("div", {
91
- role: "status",
92
- "aria-label": "Agent is thinking",
93
- className: cn("flex items-center gap-2 px-3 py-1.5", className),
94
- children: [/* @__PURE__ */ jsxs("div", {
95
- className: "flex gap-[3px]",
96
- children: [
97
- /* @__PURE__ */ jsx("span", {
98
- className: "h-[var(--indicator-dot-size)] w-[var(--indicator-dot-size)] animate-bounce rounded-full bg-[var(--brand-glow)]",
99
- style: { animationDelay: "0ms" }
100
- }),
101
- /* @__PURE__ */ jsx("span", {
102
- className: "h-[var(--indicator-dot-size)] w-[var(--indicator-dot-size)] animate-bounce rounded-full bg-[var(--brand-glow)]",
103
- style: { animationDelay: "150ms" }
104
- }),
105
- /* @__PURE__ */ jsx("span", {
106
- className: "h-[var(--indicator-dot-size)] w-[var(--indicator-dot-size)] animate-bounce rounded-full bg-[var(--brand-glow)]",
107
- style: { animationDelay: "300ms" }
108
- })
109
- ]
110
- }), elapsed > 3 && /* @__PURE__ */ jsxs("span", {
111
- className: "text-[var(--font-size-xs)] tabular-nums text-muted-foreground",
112
- children: [elapsed, "s"]
113
- })]
114
- });
115
- }
116
- //#endregion
117
- //#region src/chat/agent-timeline.tsx
118
- const TONE_STYLES = {
119
- default: {
120
- card: "border-border bg-card",
121
- text: "text-foreground",
122
- supportingText: "text-muted-foreground",
123
- icon: CircleDot
124
- },
125
- info: {
126
- card: "border-[var(--surface-info-border)] bg-[var(--surface-info-bg)]",
127
- text: "text-[var(--surface-info-text)]",
128
- supportingText: "text-[var(--surface-info-text)]",
129
- icon: Info
130
- },
131
- success: {
132
- card: "border-[var(--surface-success-border)] bg-[var(--surface-success-bg)]",
133
- text: "text-[var(--surface-success-text)]",
134
- supportingText: "text-[var(--surface-success-text)]",
135
- icon: CheckCircle2
136
- },
137
- warning: {
138
- card: "border-[var(--surface-warning-border)] bg-[var(--surface-warning-bg)]",
139
- text: "text-[var(--surface-warning-text)]",
140
- supportingText: "text-[var(--surface-warning-text)]",
141
- icon: AlertTriangle
142
- },
143
- error: {
144
- card: "border-[var(--surface-danger-border)] bg-[var(--surface-danger-bg)]",
145
- text: "text-[var(--surface-danger-text)]",
146
- supportingText: "text-[var(--surface-danger-text)]",
147
- icon: AlertTriangle
148
- }
149
- };
150
- function stepKind(item) {
151
- if (item.kind === "message") return item.role === "user" ? "user" : "prose";
152
- if (item.kind === "status" || item.kind === "artifact") return "card";
153
- return "tool";
154
- }
155
- function spacingBefore(prev, next) {
156
- if (prev === void 0) return "";
157
- if (prev === "user" || next === "user") return "mt-4";
158
- if (prev === "card" || next === "card") return "mt-2";
159
- if (prev === "tool" || next === "tool") return "mt-1";
160
- return "mt-3";
161
- }
162
- const ROW_BLEED = "-mx-3";
163
- function AssistantMessage({ item }) {
164
- return /* @__PURE__ */ jsxs("div", { children: [
165
- item.content && /* @__PURE__ */ jsx(Markdown, {
166
- className: "tangle-prose text-[var(--font-size-base)] leading-[1.5]",
167
- children: item.content
168
- }),
169
- item.isStreaming && /* @__PURE__ */ jsx("span", {
170
- "aria-hidden": true,
171
- "data-streaming-caret": "",
172
- className: "ml-0.5 inline-block h-[1em] w-0.5 animate-pulse rounded-full bg-muted-foreground align-text-bottom"
173
- }),
174
- item.toolCalls && /* @__PURE__ */ jsx("div", {
175
- className: "mt-1",
176
- children: item.toolCalls
177
- }),
178
- item.after && /* @__PURE__ */ jsx("div", {
179
- className: "mt-3 border-t border-border pt-3",
180
- children: item.after
181
- })
182
- ] });
183
- }
184
- function StatusCard({ item }) {
185
- const tone = TONE_STYLES[item.tone ?? "default"];
186
- const Icon = tone.icon;
187
- return /* @__PURE__ */ jsx("div", {
188
- className: cn("rounded-[var(--radius-lg)] border px-4 py-3", tone.card),
189
- children: /* @__PURE__ */ jsxs("div", {
190
- className: "flex items-start gap-3",
191
- children: [/* @__PURE__ */ jsx(Icon, { className: cn("mt-0.5 h-4 w-4 shrink-0", tone.text) }), /* @__PURE__ */ jsxs("div", {
192
- className: "min-w-0",
193
- children: [/* @__PURE__ */ jsx("div", {
194
- className: cn("text-sm font-medium", tone.text),
195
- children: item.label
196
- }), item.detail && /* @__PURE__ */ jsx("div", {
197
- className: cn("mt-0.5 text-sm", tone.supportingText),
198
- children: item.detail
199
- })]
200
- })]
201
- })
202
- });
203
- }
204
- function ArtifactCard({ item }) {
205
- const tone = TONE_STYLES[item.tone ?? "default"];
206
- const content = /* @__PURE__ */ jsx("div", {
207
- className: cn("rounded-[var(--radius-lg)] border px-4 py-3", tone.card),
208
- children: /* @__PURE__ */ jsxs("div", {
209
- className: "flex items-start gap-3",
210
- children: [
211
- /* @__PURE__ */ jsx("div", {
212
- className: "mt-0.5 flex h-[var(--avatar-size)] w-[var(--avatar-size)] shrink-0 items-center justify-center rounded-[var(--radius-md)] bg-muted/50 text-foreground",
213
- children: item.icon ?? /* @__PURE__ */ jsx(FileText, { className: "h-4 w-4" })
214
- }),
215
- /* @__PURE__ */ jsxs("div", {
216
- className: "min-w-0 flex-1",
217
- children: [
218
- /* @__PURE__ */ jsx("div", {
219
- className: cn("text-sm font-medium", tone.text),
220
- children: item.title
221
- }),
222
- item.description && /* @__PURE__ */ jsx("div", {
223
- className: cn("mt-1 text-sm", tone.supportingText),
224
- children: item.description
225
- }),
226
- item.meta && /* @__PURE__ */ jsx("div", {
227
- className: cn("mt-2 flex flex-wrap items-center gap-2 text-xs", tone.supportingText),
228
- children: item.meta
229
- })
230
- ]
231
- }),
232
- item.action && /* @__PURE__ */ jsx("div", {
233
- className: "shrink-0",
234
- children: item.action
235
- })
236
- ]
237
- })
238
- });
239
- if (!item.onClick) return content;
240
- return /* @__PURE__ */ jsx("div", {
241
- role: "button",
242
- tabIndex: 0,
243
- onClick: item.onClick,
244
- onKeyDown: (event) => {
245
- if (event.key === "Enter" || event.key === " ") {
246
- event.preventDefault();
247
- item.onClick?.();
248
- }
249
- },
250
- className: cn("block w-full rounded-[var(--radius-lg)] text-left transition-transform hover:-translate-y-0.5", focusRing),
251
- children: content
252
- });
253
- }
254
- /**
255
- * AgentTimeline — unified mixed-content transcript for agent-backed sandbox
256
- * sessions. Renders messages, tool rows, status cards, and artifact handoffs
257
- * as one plain column: prose at the reading size, tool calls as quiet
258
- * one-liners between the paragraphs, no connector chrome.
259
- */
260
- function AgentTimeline({ items, isThinking, emptyState, className, renderToolActions, collapseAfter }) {
261
- const [expanded, setExpanded] = useState(false);
262
- if (items.length === 0 && !isThinking) return emptyState ? /* @__PURE__ */ jsx("div", {
263
- className: cn("flex h-full items-center justify-center p-4", className),
264
- children: emptyState
265
- }) : null;
266
- const renderedItems = isThinking ? [...items, {
267
- id: "__thinking__",
268
- kind: "custom",
269
- content: /* @__PURE__ */ jsx(ThinkingIndicator, {})
270
- }] : items;
271
- const isUserMessage = (item) => item.kind === "message" && item.role === "user";
272
- const stepItems = renderedItems.filter((item) => !isUserMessage(item));
273
- const limit = collapseAfter ?? Infinity;
274
- const collapsible = stepItems.length > limit;
275
- const collapsed = collapsible && !expanded;
276
- let renderList = renderedItems;
277
- let hiddenCount = 0;
278
- if (collapsed) {
279
- const visible = [];
280
- let stepCount = 0;
281
- for (const item of renderedItems) {
282
- if (stepCount >= limit) break;
283
- visible.push(item);
284
- if (!isUserMessage(item)) stepCount += 1;
285
- }
286
- renderList = visible;
287
- hiddenCount = stepItems.length - limit;
288
- }
289
- const renderItem = (item) => {
290
- if (item.kind === "message") return item.role === "user" ? /* @__PURE__ */ jsx(UserMessage, {
291
- content: item.content,
292
- timestamp: item.timestamp
293
- }) : /* @__PURE__ */ jsx(AssistantMessage, { item });
294
- if (item.kind === "tool") return /* @__PURE__ */ jsx(ToolCallStep, {
295
- type: item.call.type,
296
- label: item.call.label,
297
- status: item.call.status,
298
- detail: item.call.detail,
299
- output: item.call.output,
300
- duration: item.call.duration,
301
- part: item.part,
302
- actions: item.part ? renderToolActions?.(item.part) : void 0
303
- });
304
- if (item.kind === "tool_group") return /* @__PURE__ */ jsx(ToolCallGroup, {
305
- title: item.title,
306
- children: item.calls.map((call, callIndex) => {
307
- const part = item.parts?.[callIndex];
308
- return /* @__PURE__ */ jsx(ToolCallStep, {
309
- type: call.type,
310
- label: call.label,
311
- status: call.status,
312
- detail: call.detail,
313
- output: call.output,
314
- duration: call.duration,
315
- part,
316
- actions: part ? renderToolActions?.(part) : void 0
317
- }, call.id);
318
- })
319
- });
320
- if (item.kind === "status") return /* @__PURE__ */ jsx(StatusCard, { item });
321
- if (item.kind === "artifact") return /* @__PURE__ */ jsx(ArtifactCard, { item });
322
- return item.content;
323
- };
324
- return /* @__PURE__ */ jsxs("div", {
325
- className: cn("mx-auto flex w-full max-w-5xl flex-col px-4 py-4", className),
326
- children: [renderList.map((item, index) => {
327
- const kind = stepKind(item);
328
- const prev = index > 0 ? stepKind(renderList[index - 1]) : void 0;
329
- return /* @__PURE__ */ jsx("div", {
330
- "data-timeline-step": kind,
331
- className: cn(spacingBefore(prev, kind), kind === "tool" && ROW_BLEED),
332
- children: renderItem(item)
333
- }, item.id);
334
- }), collapsible ? /* @__PURE__ */ jsx("button", {
335
- type: "button",
336
- onClick: () => setExpanded((value) => !value),
337
- className: "mt-2 self-start text-xs font-medium text-muted-foreground transition-colors hover:text-foreground",
338
- children: collapsed ? `Show ${hiddenCount} more step${hiddenCount === 1 ? "" : "s"}` : "Show less"
339
- }) : null]
340
- });
341
- }
342
- //#endregion
343
- //#region src/chat/chat-container.tsx
344
- const OPENUI_NODE_TYPES = /* @__PURE__ */ new Set([
345
- "heading",
346
- "text",
347
- "badge",
348
- "stat",
349
- "key_value",
350
- "code",
351
- "markdown",
352
- "table",
353
- "actions",
354
- "separator",
355
- "stack",
356
- "grid",
357
- "card"
358
- ]);
359
- function isOpenUINode(value) {
360
- return typeof value === "object" && value !== null && "type" in value && typeof value.type === "string" && OPENUI_NODE_TYPES.has(value.type);
361
- }
362
- function extractOpenUISchema(output) {
363
- if (output == null) return null;
364
- if (isOpenUINode(output)) return [output];
365
- if (Array.isArray(output) && output.length > 0 && output.every(isOpenUINode)) return output;
366
- if (typeof output === "object" && !Array.isArray(output)) {
367
- const obj = output;
368
- for (const key of [
369
- "openui",
370
- "schema",
371
- "ui"
372
- ]) if (obj[key]) {
373
- const inner = obj[key];
374
- if (isOpenUINode(inner)) return [inner];
375
- if (Array.isArray(inner) && inner.length > 0 && inner.every(isOpenUINode)) return inner;
376
- }
377
- }
378
- if (typeof output === "string") try {
379
- return extractOpenUISchema(JSON.parse(output));
380
- } catch {
381
- return null;
382
- }
383
- return null;
384
- }
385
- function formatUnknown(value) {
386
- if (value == null) return void 0;
387
- if (typeof value === "string") return value;
388
- try {
389
- return JSON.stringify(value, null, 2);
390
- } catch {
391
- return String(value);
392
- }
393
- }
394
- function createdAtFromMessage(message) {
395
- return message.time?.created ? new Date(message.time.created) : void 0;
396
- }
397
- function mapToolPartToTimelineType(part) {
398
- switch (part.tool.toLowerCase().replace(/^tool:/, "")) {
399
- case "bash":
400
- case "shell":
401
- case "command":
402
- case "execute": return "bash";
403
- case "write":
404
- case "write_file":
405
- case "create_file": return "write";
406
- case "read":
407
- case "read_file":
408
- case "cat": return "read";
409
- case "edit":
410
- case "patch":
411
- case "sed": return "edit";
412
- case "glob":
413
- case "find": return "glob";
414
- case "ls": return "list";
415
- case "grep":
416
- case "search":
417
- case "rg": return "grep";
418
- case "inspect": return "inspect";
419
- default: return "unknown";
420
- }
421
- }
422
- function buildTimelineItems(messages, partMap, isStreaming, onOpenUIAction, enableOpenUI = true) {
423
- const items = [];
424
- let latestUserIndex = -1;
425
- for (let index = messages.length - 1; index >= 0; index -= 1) if (messages[index].role === "user") {
426
- latestUserIndex = index;
427
- break;
428
- }
429
- const lastAssistantMessage = [...latestUserIndex >= 0 ? messages.slice(latestUserIndex + 1) : messages].reverse().find((message) => message.role === "assistant");
430
- const toToolCall = (part) => {
431
- const meta = getToolDisplayMetadata(part);
432
- const start = part.state.time?.start;
433
- const end = part.state.time?.end;
434
- return {
435
- id: part.id,
436
- type: mapToolPartToTimelineType(part),
437
- label: meta.title,
438
- status: part.state.status === "completed" ? "success" : part.state.status === "error" ? "error" : "running",
439
- detail: meta.commandSnippet ?? meta.targetPath ?? meta.description,
440
- output: formatUnknown(part.state.output),
441
- duration: start && end ? end - start : void 0
442
- };
443
- };
444
- for (const message of messages) {
445
- const parts = partMap[message.id] ?? [];
446
- if (message.role === "user") {
447
- const content = parts.filter((part) => part.type === "text").map((part) => part.text).join("\n").trim();
448
- if (!content) continue;
449
- items.push({
450
- id: message.id,
451
- kind: "message",
452
- role: "user",
453
- content,
454
- timestamp: createdAtFromMessage(message)
455
- });
456
- continue;
457
- }
458
- const toolBuffer = [];
459
- const flushToolBuffer = (index) => {
460
- if (toolBuffer.length === 0) return;
461
- if (toolBuffer.length === 1) items.push({
462
- id: `${message.id}-tool-${toolBuffer[0].id}`,
463
- kind: "tool",
464
- call: toToolCall(toolBuffer[0]),
465
- part: toolBuffer[0]
466
- });
467
- else items.push({
468
- id: `${message.id}-tool-group-${index}`,
469
- kind: "tool_group",
470
- title: "Tool activity",
471
- parts: [...toolBuffer],
472
- calls: toolBuffer.map((part) => toToolCall(part))
473
- });
474
- if (enableOpenUI) for (const part of toolBuffer) {
475
- if (part.state.status !== "completed" || !part.state.output) continue;
476
- const schema = extractOpenUISchema(part.state.output);
477
- if (!schema) continue;
478
- items.push({
479
- id: `${message.id}-openui-${part.id}`,
480
- kind: "custom",
481
- content: /* @__PURE__ */ jsx("div", {
482
- className: "my-2 rounded-[var(--radius-lg)] border border-border bg-card p-4 shadow-[var(--shadow-card)]",
483
- children: /* @__PURE__ */ jsx(OpenUIArtifactRenderer, {
484
- schema,
485
- onAction: onOpenUIAction
486
- })
487
- })
488
- });
489
- }
490
- toolBuffer.length = 0;
491
- };
492
- parts.forEach((part, index) => {
493
- const itemId = `${message.id}-${index}`;
494
- if (part.type === "tool") {
495
- toolBuffer.push(part);
496
- return;
497
- }
498
- flushToolBuffer(index);
499
- if (part.type === "text" && !part.synthetic && part.text.trim()) {
500
- if (enableOpenUI) {
501
- const jsonMatch = part.text.match(/```(?:json)?\s*\n([\s\S]*?)\n```/);
502
- if (jsonMatch) {
503
- const schema = extractOpenUISchema(jsonMatch[1]);
504
- if (schema) {
505
- const beforeJson = part.text.slice(0, part.text.indexOf("```")).trim();
506
- if (beforeJson) items.push({
507
- id: `${itemId}-text`,
508
- kind: "message",
509
- role: "assistant",
510
- content: beforeJson,
511
- timestamp: createdAtFromMessage(message)
512
- });
513
- items.push({
514
- id: `${itemId}-openui`,
515
- kind: "custom",
516
- content: /* @__PURE__ */ jsx("div", {
517
- className: "my-2 rounded-[var(--radius-lg)] border border-border bg-card p-4 shadow-[var(--shadow-card)]",
518
- children: /* @__PURE__ */ jsx(OpenUIArtifactRenderer, {
519
- schema,
520
- onAction: onOpenUIAction
521
- })
522
- })
523
- });
524
- const afterJson = part.text.slice(part.text.lastIndexOf("```") + 3).trim();
525
- if (afterJson) items.push({
526
- id: `${itemId}-after`,
527
- kind: "message",
528
- role: "assistant",
529
- content: afterJson,
530
- timestamp: createdAtFromMessage(message)
531
- });
532
- return;
533
- }
534
- }
535
- }
536
- items.push({
537
- id: itemId,
538
- kind: "message",
539
- role: "assistant",
540
- content: part.text,
541
- timestamp: createdAtFromMessage(message),
542
- isStreaming: isStreaming && lastAssistantMessage?.id === message.id && index === parts.length - 1
543
- });
544
- return;
545
- }
546
- if (part.type === "reasoning") {
547
- items.push({
548
- id: itemId,
549
- kind: "custom",
550
- content: /* @__PURE__ */ jsx(InlineThinkingItem, {
551
- part,
552
- defaultOpen: isStreaming && lastAssistantMessage?.id === message.id
553
- })
554
- });
555
- return;
556
- }
557
- });
558
- flushToolBuffer(parts.length);
559
- }
560
- return {
561
- items,
562
- showThinking: isStreaming && latestUserIndex >= 0 && (lastAssistantMessage == null || !items.some((item) => item.kind === "message" && item.role === "assistant" && item.id.startsWith(lastAssistantMessage.id)))
563
- };
564
- }
565
- /**
566
- * Chat transcript container: message list + auto-scroll.
567
- * Orchestrates useRunGroups, useRunCollapseState, and useAutoScroll.
568
- */
569
- const ChatContainer = memo(({ messages, partMap, isStreaming, branding, className, renderToolDetail, presentation = "runs", onOpenUIAction, enableOpenUI = true, renderRunActions, renderUserMessageActions, renderToolActions, renderTimelineToolActions, collapseTimelineAfter }) => {
570
- const scrollRef = useRef(null);
571
- const groups = useRunGroups({
572
- messages,
573
- partMap,
574
- isStreaming
575
- });
576
- const runs = groups.filter((g) => g.type === "run").map((g) => g.run);
577
- const { isCollapsed, toggleCollapse } = useRunCollapseState(runs);
578
- const { isAtBottom, scrollToBottom } = useAutoScroll(scrollRef, [
579
- messages,
580
- partMap,
581
- isStreaming
582
- ]);
583
- const timeline = useMemo(() => buildTimelineItems(messages, partMap, isStreaming, onOpenUIAction, enableOpenUI), [
584
- messages,
585
- partMap,
586
- isStreaming,
587
- onOpenUIAction,
588
- enableOpenUI
589
- ]);
590
- return /* @__PURE__ */ jsxs("div", {
591
- className: cn("flex h-full flex-col", className),
592
- children: [/* @__PURE__ */ jsx("div", {
593
- ref: scrollRef,
594
- className: "flex-1 overflow-y-auto [scrollbar-gutter:stable]",
595
- children: messages.length === 0 ? /* @__PURE__ */ jsx("div", {
596
- className: "flex h-full items-center justify-center",
597
- children: /* @__PURE__ */ jsx("div", {
598
- className: "max-w-md text-center",
599
- children: /* @__PURE__ */ jsx("div", {
600
- className: "text-sm font-medium text-muted-foreground",
601
- children: "Start a conversation."
602
- })
603
- })
604
- }) : presentation === "timeline" ? /* @__PURE__ */ jsx("div", {
605
- className: "mx-auto flex min-h-full w-full max-w-3xl flex-col justify-end",
606
- children: /* @__PURE__ */ jsx(AgentTimeline, {
607
- items: timeline.items,
608
- isThinking: timeline.showThinking,
609
- renderToolActions: renderTimelineToolActions,
610
- collapseAfter: collapseTimelineAfter
611
- })
612
- }) : /* @__PURE__ */ jsx("div", {
613
- className: "mx-auto flex min-h-full w-full max-w-3xl flex-col justify-end",
614
- children: /* @__PURE__ */ jsx(MessageList, {
615
- groups,
616
- partMap,
617
- isCollapsed,
618
- onToggleCollapse: toggleCollapse,
619
- branding,
620
- renderToolDetail,
621
- renderRunActions,
622
- renderUserMessageActions,
623
- renderToolActions
624
- })
625
- })
626
- }), !isAtBottom && /* @__PURE__ */ jsx("div", {
627
- className: "relative z-10 -mt-10 flex justify-center",
628
- children: /* @__PURE__ */ jsxs("button", {
629
- onClick: scrollToBottom,
630
- className: cn("flex items-center gap-1.5 px-3 py-1.5 rounded-full", "border border-border bg-card shadow-[0_6px_16px_rgba(15,23,42,0.08)]", "text-xs text-foreground transition-colors hover:bg-accent", focusRing),
631
- children: [/* @__PURE__ */ jsx(ArrowDown, { className: "w-3 h-3" }), "Scroll to bottom"]
632
- })
633
- })]
634
- });
635
- });
636
- ChatContainer.displayName = "ChatContainer";
637
- //#endregion
638
- //#region src/chat/chat-message.tsx
639
- function ChatMessage({ role, content, toolCalls, isStreaming, timestamp, className, userLabel = "You", assistantLabel = "Agent", hideRoleLabel }) {
640
- const isUser = role === "user";
641
- const isAssistant = role === "assistant";
642
- return /* @__PURE__ */ jsxs("div", {
643
- className: cn("flex flex-col gap-1", isUser ? "items-end" : "items-start", className),
644
- children: [!hideRoleLabel && /* @__PURE__ */ jsxs("div", {
645
- className: cn("flex items-center gap-2 px-1", isUser && "flex-row-reverse"),
646
- children: [/* @__PURE__ */ jsx("span", {
647
- className: "font-medium text-foreground text-xs",
648
- children: isUser ? userLabel : assistantLabel
649
- }), timestamp && /* @__PURE__ */ jsx("span", {
650
- className: "text-muted-foreground text-xs",
651
- children: formatTime(timestamp)
652
- })]
653
- }), /* @__PURE__ */ jsxs("div", {
654
- className: cn("min-w-0 max-w-[85%] space-y-1", isUser ? "rounded-[var(--radius-lg)] bg-foreground px-[var(--chat-message-px)] py-[var(--chat-message-py)] text-background" : isAssistant ? "text-foreground" : "rounded-[var(--radius-lg)] border border-border bg-card px-[var(--chat-message-px)] py-[var(--chat-message-py)]"),
655
- children: [isUser ? /* @__PURE__ */ jsx("div", {
656
- className: "whitespace-pre-wrap text-[var(--font-size-base)] leading-[var(--line-height-base)]",
657
- children: content
658
- }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [content && /* @__PURE__ */ jsx(Markdown, {
659
- className: "tangle-prose text-[var(--font-size-base)] leading-[var(--line-height-base)]",
660
- children: content
661
- }), isStreaming && /* @__PURE__ */ jsx("span", { className: "ml-0.5 inline-block h-4 w-2 animate-pulse rounded-sm bg-[var(--brand-cool)] align-text-bottom" })] }), toolCalls]
662
- })]
663
- });
664
- }
665
- function formatTime(date) {
666
- return date.toLocaleTimeString(void 0, {
667
- hour: "numeric",
668
- minute: "2-digit"
669
- });
670
- }
671
- //#endregion
672
- export { MessageList as a, ThinkingIndicator as i, ChatContainer as n, UserMessage as o, AgentTimeline as r, ChatMessage as t };