@tangle-network/ui 1.0.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 (220) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/LICENSE +21 -0
  3. package/README.md +33 -0
  4. package/dist/active-sessions-store-CeOmXgv5.d.ts +85 -0
  5. package/dist/artifact-pane-DvJyPWV4.d.ts +24 -0
  6. package/dist/auth.d.ts +74 -0
  7. package/dist/auth.js +15 -0
  8. package/dist/button-CMQuQEW_.d.ts +17 -0
  9. package/dist/chat.d.ts +232 -0
  10. package/dist/chat.js +30 -0
  11. package/dist/chunk-2NFQRQOD.js +1009 -0
  12. package/dist/chunk-2VH6PUXD.js +186 -0
  13. package/dist/chunk-34A66VBG.js +214 -0
  14. package/dist/chunk-3OI2QKFD.js +0 -0
  15. package/dist/chunk-4CLN43XT.js +45 -0
  16. package/dist/chunk-54SQQMMM.js +156 -0
  17. package/dist/chunk-5Z5ZYMOJ.js +0 -0
  18. package/dist/chunk-66BNMOVT.js +167 -0
  19. package/dist/chunk-6BGQA4BQ.js +0 -0
  20. package/dist/chunk-7UO2ZMRQ.js +133 -0
  21. package/dist/chunk-BX6AQMUS.js +183 -0
  22. package/dist/chunk-CD53GZOM.js +59 -0
  23. package/dist/chunk-CSAIKY36.js +54 -0
  24. package/dist/chunk-EEE55AVS.js +1201 -0
  25. package/dist/chunk-GYPQXTJU.js +230 -0
  26. package/dist/chunk-HFL6R6IF.js +37 -0
  27. package/dist/chunk-HJKCSXCH.js +737 -0
  28. package/dist/chunk-LISXUB4D.js +1222 -0
  29. package/dist/chunk-LQS34IGP.js +0 -0
  30. package/dist/chunk-MKTSMWVD.js +109 -0
  31. package/dist/chunk-NKDZ7GZE.js +192 -0
  32. package/dist/chunk-OEX7NZE3.js +321 -0
  33. package/dist/chunk-Q56BYXQF.js +61 -0
  34. package/dist/chunk-Q7EIIWTC.js +0 -0
  35. package/dist/chunk-REJESC5U.js +117 -0
  36. package/dist/chunk-RQGKSCEZ.js +0 -0
  37. package/dist/chunk-RQHJBTEU.js +10 -0
  38. package/dist/chunk-TMFOPHHN.js +299 -0
  39. package/dist/chunk-XGKULLYE.js +40 -0
  40. package/dist/chunk-XIHMJ7ZQ.js +614 -0
  41. package/dist/chunk-YJ2G3XO5.js +1048 -0
  42. package/dist/chunk-YNN4O57I.js +754 -0
  43. package/dist/code-block-DjXf8eOG.d.ts +19 -0
  44. package/dist/document-editor-pane-A5LT5H4N.js +12 -0
  45. package/dist/document-editor-pane-DyDEX_Zm.d.ts +124 -0
  46. package/dist/editor.d.ts +120 -0
  47. package/dist/editor.js +34 -0
  48. package/dist/files.d.ts +175 -0
  49. package/dist/files.js +20 -0
  50. package/dist/hooks.d.ts +56 -0
  51. package/dist/hooks.js +41 -0
  52. package/dist/index.d.ts +43 -0
  53. package/dist/index.js +446 -0
  54. package/dist/markdown.d.ts +15 -0
  55. package/dist/markdown.js +14 -0
  56. package/dist/message-BHWbxBtT.d.ts +15 -0
  57. package/dist/openui.d.ts +115 -0
  58. package/dist/openui.js +12 -0
  59. package/dist/parts-dj7AcUg0.d.ts +36 -0
  60. package/dist/primitives.d.ts +332 -0
  61. package/dist/primitives.js +191 -0
  62. package/dist/run-PfLmDAox.d.ts +41 -0
  63. package/dist/run.d.ts +69 -0
  64. package/dist/run.js +36 -0
  65. package/dist/sdk-hooks.d.ts +285 -0
  66. package/dist/sdk-hooks.js +31 -0
  67. package/dist/stores.d.ts +17 -0
  68. package/dist/stores.js +76 -0
  69. package/dist/tool-call-feed-Bs3MyQMT.d.ts +68 -0
  70. package/dist/tool-display-z4JcDmMQ.d.ts +32 -0
  71. package/dist/tool-previews.d.ts +48 -0
  72. package/dist/tool-previews.js +21 -0
  73. package/dist/types.d.ts +19 -0
  74. package/dist/types.js +1 -0
  75. package/dist/utils.d.ts +45 -0
  76. package/dist/utils.js +32 -0
  77. package/package.json +193 -0
  78. package/src/auth/auth.tsx +228 -0
  79. package/src/auth/index.ts +13 -0
  80. package/src/auth/login-layout.tsx +46 -0
  81. package/src/chat/agent-timeline.stories.tsx +429 -0
  82. package/src/chat/agent-timeline.tsx +360 -0
  83. package/src/chat/chat-container.tsx +486 -0
  84. package/src/chat/chat-input.stories.tsx +142 -0
  85. package/src/chat/chat-input.tsx +389 -0
  86. package/src/chat/chat-message.stories.tsx +237 -0
  87. package/src/chat/chat-message.tsx +129 -0
  88. package/src/chat/index.ts +18 -0
  89. package/src/chat/message-list.stories.tsx +336 -0
  90. package/src/chat/message-list.tsx +79 -0
  91. package/src/chat/thinking-indicator.stories.tsx +56 -0
  92. package/src/chat/thinking-indicator.tsx +30 -0
  93. package/src/chat/user-message.stories.tsx +92 -0
  94. package/src/chat/user-message.tsx +43 -0
  95. package/src/editor/document-editor-pane.tsx +351 -0
  96. package/src/editor/editor-provider.tsx +428 -0
  97. package/src/editor/editor-toolbar.tsx +130 -0
  98. package/src/editor/index.ts +31 -0
  99. package/src/editor/markdown-conversion.ts +21 -0
  100. package/src/editor/markdown-document-editor.tsx +137 -0
  101. package/src/editor/tiptap-editor.tsx +331 -0
  102. package/src/editor/use-editor.ts +221 -0
  103. package/src/files/file-artifact-pane.tsx +183 -0
  104. package/src/files/file-preview.tsx +342 -0
  105. package/src/files/file-tabs.tsx +71 -0
  106. package/src/files/file-tree.tsx +258 -0
  107. package/src/files/index.ts +17 -0
  108. package/src/files/rich-file-tree.stories.tsx +104 -0
  109. package/src/files/rich-file-tree.test.tsx +42 -0
  110. package/src/files/rich-file-tree.tsx +232 -0
  111. package/src/hooks/index.ts +10 -0
  112. package/src/hooks/use-auth.ts +153 -0
  113. package/src/hooks/use-auto-scroll.ts +59 -0
  114. package/src/hooks/use-dropdown-menu.ts +40 -0
  115. package/src/hooks/use-live-time.test.tsx +40 -0
  116. package/src/hooks/use-live-time.ts +27 -0
  117. package/src/hooks/use-realtime-session.ts +319 -0
  118. package/src/hooks/use-run-collapse-state.ts +25 -0
  119. package/src/hooks/use-run-groups.ts +111 -0
  120. package/src/hooks/use-sdk-session.ts +575 -0
  121. package/src/hooks/use-sse-stream.ts +475 -0
  122. package/src/hooks/use-tool-call-stream.ts +96 -0
  123. package/src/index.ts +14 -0
  124. package/src/lib/utils.ts +6 -0
  125. package/src/markdown/code-block.tsx +198 -0
  126. package/src/markdown/index.ts +2 -0
  127. package/src/markdown/markdown.stories.tsx +190 -0
  128. package/src/markdown/markdown.tsx +62 -0
  129. package/src/openui/index.ts +20 -0
  130. package/src/openui/openui-artifact-renderer.tsx +542 -0
  131. package/src/primitives/artifact-pane.tsx +91 -0
  132. package/src/primitives/avatar.stories.tsx +95 -0
  133. package/src/primitives/avatar.tsx +47 -0
  134. package/src/primitives/badge.stories.tsx +57 -0
  135. package/src/primitives/badge.tsx +97 -0
  136. package/src/primitives/button.stories.tsx +48 -0
  137. package/src/primitives/button.tsx +115 -0
  138. package/src/primitives/card.stories.tsx +53 -0
  139. package/src/primitives/card.tsx +98 -0
  140. package/src/primitives/code-block.stories.tsx +115 -0
  141. package/src/primitives/code-block.tsx +22 -0
  142. package/src/primitives/design-tokens.stories.tsx +162 -0
  143. package/src/primitives/dialog.stories.tsx +176 -0
  144. package/src/primitives/dialog.tsx +137 -0
  145. package/src/primitives/drop-zone.stories.tsx +123 -0
  146. package/src/primitives/drop-zone.tsx +131 -0
  147. package/src/primitives/dropdown-menu.stories.tsx +122 -0
  148. package/src/primitives/dropdown-menu.tsx +214 -0
  149. package/src/primitives/empty-state.stories.tsx +81 -0
  150. package/src/primitives/empty-state.tsx +40 -0
  151. package/src/primitives/index.ts +118 -0
  152. package/src/primitives/input.stories.tsx +113 -0
  153. package/src/primitives/input.tsx +136 -0
  154. package/src/primitives/label.stories.tsx +84 -0
  155. package/src/primitives/label.tsx +24 -0
  156. package/src/primitives/progress.stories.tsx +93 -0
  157. package/src/primitives/progress.tsx +50 -0
  158. package/src/primitives/segmented-control.test.tsx +328 -0
  159. package/src/primitives/segmented-control.tsx +154 -0
  160. package/src/primitives/select.stories.tsx +164 -0
  161. package/src/primitives/select.tsx +158 -0
  162. package/src/primitives/sidebar-drop-zone.stories.tsx +100 -0
  163. package/src/primitives/sidebar-drop-zone.tsx +149 -0
  164. package/src/primitives/skeleton.stories.tsx +79 -0
  165. package/src/primitives/skeleton.tsx +55 -0
  166. package/src/primitives/stat-card.stories.tsx +137 -0
  167. package/src/primitives/stat-card.tsx +97 -0
  168. package/src/primitives/switch.stories.tsx +85 -0
  169. package/src/primitives/switch.tsx +28 -0
  170. package/src/primitives/table.stories.tsx +170 -0
  171. package/src/primitives/table.tsx +116 -0
  172. package/src/primitives/tabs.stories.tsx +180 -0
  173. package/src/primitives/tabs.tsx +71 -0
  174. package/src/primitives/terminal-display.stories.tsx +191 -0
  175. package/src/primitives/terminal-display.tsx +189 -0
  176. package/src/primitives/theme-toggle.stories.tsx +32 -0
  177. package/src/primitives/theme-toggle.tsx +96 -0
  178. package/src/primitives/toast.stories.tsx +155 -0
  179. package/src/primitives/toast.tsx +190 -0
  180. package/src/primitives/upload-progress.stories.tsx +120 -0
  181. package/src/primitives/upload-progress.tsx +110 -0
  182. package/src/run/expanded-tool-detail.stories.tsx +182 -0
  183. package/src/run/expanded-tool-detail.tsx +186 -0
  184. package/src/run/index.ts +13 -0
  185. package/src/run/inline-thinking-item.stories.tsx +136 -0
  186. package/src/run/inline-thinking-item.tsx +120 -0
  187. package/src/run/inline-tool-item.stories.tsx +222 -0
  188. package/src/run/inline-tool-item.tsx +190 -0
  189. package/src/run/run-group.stories.tsx +322 -0
  190. package/src/run/run-group.tsx +569 -0
  191. package/src/run/run-item-primitives.tsx +17 -0
  192. package/src/run/tool-call-feed.stories.tsx +294 -0
  193. package/src/run/tool-call-feed.tsx +192 -0
  194. package/src/run/tool-call-step.stories.tsx +198 -0
  195. package/src/run/tool-call-step.tsx +240 -0
  196. package/src/sdk-hooks.ts +38 -0
  197. package/src/stores/active-sessions-store.ts +455 -0
  198. package/src/stores/chat-store.ts +43 -0
  199. package/src/stores/index.ts +2 -0
  200. package/src/tool-previews/command-preview.tsx +116 -0
  201. package/src/tool-previews/diff-preview.tsx +85 -0
  202. package/src/tool-previews/glob-results-preview.tsx +98 -0
  203. package/src/tool-previews/grep-results-preview.tsx +157 -0
  204. package/src/tool-previews/index.ts +22 -0
  205. package/src/tool-previews/preview-primitives.tsx +84 -0
  206. package/src/tool-previews/question-preview.tsx +101 -0
  207. package/src/tool-previews/web-search-preview.tsx +117 -0
  208. package/src/tool-previews/write-file-preview.tsx +80 -0
  209. package/src/types/branding.ts +11 -0
  210. package/src/types/index.ts +5 -0
  211. package/src/types/message.ts +13 -0
  212. package/src/types/parts.ts +51 -0
  213. package/src/types/run.ts +56 -0
  214. package/src/types/tool-display.ts +41 -0
  215. package/src/utils/copy-text.ts +30 -0
  216. package/src/utils/format.test.ts +43 -0
  217. package/src/utils/format.ts +56 -0
  218. package/src/utils/index.ts +10 -0
  219. package/src/utils/time-ago.ts +9 -0
  220. package/src/utils/tool-display.ts +238 -0
@@ -0,0 +1,240 @@
1
+ /**
2
+ * ToolCallStep — renders a single agent tool invocation as a collapsible activity step.
3
+ *
4
+ * Inspired by Conductor's workspace activity feed.
5
+ * Each step shows: icon, label, optional output, expandable detail.
6
+ */
7
+
8
+ import { useState, type ReactNode } from "react";
9
+ import {
10
+ Terminal,
11
+ FileText,
12
+ FileCode,
13
+ Search,
14
+ CheckCircle,
15
+ ChevronRight,
16
+ Loader2,
17
+ FolderOpen,
18
+ Download,
19
+ Pencil,
20
+ Eye,
21
+ } from "lucide-react";
22
+ import { cn } from "../lib/utils";
23
+ import { CodeBlock } from "../markdown/code-block";
24
+
25
+ export type ToolCallType =
26
+ | "bash"
27
+ | "read"
28
+ | "write"
29
+ | "edit"
30
+ | "glob"
31
+ | "grep"
32
+ | "list"
33
+ | "download"
34
+ | "inspect"
35
+ | "audit"
36
+ | "unknown";
37
+
38
+ export type ToolCallStatus = "running" | "success" | "error";
39
+
40
+ export interface ToolCallStepProps {
41
+ type: ToolCallType;
42
+ label: string;
43
+ status: ToolCallStatus;
44
+ detail?: string;
45
+ output?: string;
46
+ /** Override syntax highlighting language; inferred from detail path if omitted */
47
+ language?: string;
48
+ duration?: number;
49
+ className?: string;
50
+ }
51
+
52
+ const EXT_LANGUAGE: Record<string, string> = {
53
+ ts: "typescript", tsx: "typescript",
54
+ js: "javascript", jsx: "javascript", mjs: "javascript", cjs: "javascript",
55
+ css: "css", scss: "scss",
56
+ json: "json", jsonc: "json",
57
+ md: "markdown", mdx: "markdown",
58
+ py: "python",
59
+ sh: "bash", bash: "bash", zsh: "bash",
60
+ html: "html", htm: "html",
61
+ yaml: "yaml", yml: "yaml",
62
+ toml: "toml",
63
+ rs: "rust",
64
+ go: "go",
65
+ sql: "sql",
66
+ xml: "xml",
67
+ }
68
+
69
+ function inferLanguage(detail?: string, language?: string): string | undefined {
70
+ if (language) return language
71
+ if (!detail) return undefined
72
+ const ext = detail.split(".").pop()?.toLowerCase()
73
+ return ext ? EXT_LANGUAGE[ext] : undefined
74
+ }
75
+
76
+ function isFilePath(detail: string): boolean {
77
+ return /[/\\]/.test(detail) || /\.\w{1,6}$/.test(detail)
78
+ }
79
+
80
+ function FilePathChip({ path }: { path: string }) {
81
+ const parts = path.replace(/\\/g, "/").split("/")
82
+ const filename = parts.pop() ?? path
83
+ const dir = parts.length > 0 ? parts.join("/") + "/" : ""
84
+ return (
85
+ <div className="flex items-center gap-1.5 rounded-[var(--radius-sm)] border border-border bg-background px-2.5 py-1.5 font-mono text-xs min-w-0">
86
+ <FileCode className="h-3.5 w-3.5 shrink-0 text-primary" />
87
+ {dir && (
88
+ <span className="truncate text-muted-foreground">{dir}</span>
89
+ )}
90
+ <span className="shrink-0 font-semibold text-foreground">{filename}</span>
91
+ </div>
92
+ )
93
+ }
94
+
95
+ const ICONS: Record<ToolCallType, typeof Terminal> = {
96
+ bash: Terminal,
97
+ read: Eye,
98
+ write: FileText,
99
+ edit: Pencil,
100
+ glob: FolderOpen,
101
+ grep: Search,
102
+ list: FolderOpen,
103
+ download: Download,
104
+ inspect: Search,
105
+ audit: CheckCircle,
106
+ unknown: FileCode,
107
+ };
108
+
109
+ const STATUS_COLORS: Record<ToolCallStatus, string> = {
110
+ running: "text-primary",
111
+ success: "text-[var(--code-success)]",
112
+ error: "text-[var(--code-error)]",
113
+ };
114
+
115
+ export function ToolCallStep({
116
+ type,
117
+ label,
118
+ status,
119
+ detail,
120
+ output,
121
+ language,
122
+ duration,
123
+ className,
124
+ }: ToolCallStepProps) {
125
+ const [expanded, setExpanded] = useState(false);
126
+ const Icon = ICONS[type] || ICONS.unknown;
127
+ const hasExpandable = !!(detail || output);
128
+ const lang = inferLanguage(detail, language);
129
+
130
+ return (
131
+ <div
132
+ className={cn(
133
+ "group overflow-hidden rounded-[var(--radius-lg)] border bg-card transition-colors",
134
+ status === "running" && "border-border",
135
+ status === "success" && "border-border hover:border-primary/20",
136
+ status === "error" && "border-[var(--surface-danger-border)]",
137
+ className,
138
+ )}
139
+ >
140
+ <button
141
+ onClick={() => hasExpandable && setExpanded(!expanded)}
142
+ disabled={!hasExpandable}
143
+ className={cn(
144
+ "flex w-full items-center gap-2.5 px-3 py-2 text-left text-sm",
145
+ hasExpandable && "cursor-pointer",
146
+ )}
147
+ >
148
+ <div
149
+ className={cn(
150
+ "flex h-6 w-6 shrink-0 items-center justify-center rounded-[var(--radius-sm)] border",
151
+ status === "running" && "border-[var(--border-accent)] bg-[var(--accent-surface-soft)] text-primary",
152
+ status === "success" && "border-[var(--surface-success-border)] bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]",
153
+ status === "error" && "border-[var(--surface-danger-border)] bg-[var(--surface-danger-bg)] text-[var(--surface-danger-text)]",
154
+ )}
155
+ >
156
+ {status === "running" ? (
157
+ <Loader2 className="h-3 w-3 animate-spin shrink-0" />
158
+ ) : (
159
+ <Icon className={cn("h-3 w-3 shrink-0", STATUS_COLORS[status])} />
160
+ )}
161
+ </div>
162
+
163
+ {/* Label */}
164
+ <span className="truncate flex-1 font-sans text-foreground">
165
+ {label}
166
+ </span>
167
+
168
+ <span
169
+ className={cn(
170
+ "rounded-full border px-2 py-0.5 text-[11px] font-semibold uppercase tracking-[0.06em]",
171
+ status === "running" &&
172
+ "border-border bg-[var(--accent-surface-soft)] text-primary",
173
+ status === "success" &&
174
+ "border-[var(--surface-success-border)] bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]",
175
+ status === "error" && "border-[var(--surface-danger-border)] bg-[var(--surface-danger-bg)] text-[var(--surface-danger-text)]",
176
+ )}
177
+ >
178
+ {status}
179
+ </span>
180
+
181
+ {/* Duration */}
182
+ {duration !== undefined && status !== "running" && (
183
+ <span className="shrink-0 text-xs tabular-nums text-muted-foreground">
184
+ {duration < 1000 ? `${duration}ms` : `${(duration / 1000).toFixed(1)}s`}
185
+ </span>
186
+ )}
187
+
188
+ {/* Expand chevron */}
189
+ {hasExpandable && (
190
+ <ChevronRight
191
+ className={cn(
192
+ "h-3 w-3 text-muted-foreground transition-transform shrink-0",
193
+ expanded && "rotate-90",
194
+ )}
195
+ />
196
+ )}
197
+ </button>
198
+
199
+ {/* Expandable content */}
200
+ {expanded && (detail || output) && (
201
+ <div className="space-y-2 border-t border-border bg-muted px-3 py-2.5">
202
+ {detail && (
203
+ isFilePath(detail)
204
+ ? <FilePathChip path={detail} />
205
+ : <div className="text-xs font-mono text-muted-foreground">{detail}</div>
206
+ )}
207
+ {output && (
208
+ <CodeBlock
209
+ code={output}
210
+ language={lang}
211
+ className="max-h-72 overflow-auto text-xs"
212
+ />
213
+ )}
214
+ </div>
215
+ )}
216
+ </div>
217
+ );
218
+ }
219
+
220
+ /**
221
+ * ToolCallGroup — groups multiple tool calls under a heading.
222
+ */
223
+ export interface ToolCallGroupProps {
224
+ title?: string;
225
+ children: ReactNode;
226
+ className?: string;
227
+ }
228
+
229
+ export function ToolCallGroup({ title, children, className }: ToolCallGroupProps) {
230
+ return (
231
+ <div className={cn("my-2 space-y-2", className)}>
232
+ {title && (
233
+ <div className="mb-1 px-1 text-xs font-medium uppercase tracking-wider text-muted-foreground">
234
+ {title}
235
+ </div>
236
+ )}
237
+ {children}
238
+ </div>
239
+ );
240
+ }
@@ -0,0 +1,38 @@
1
+ export { useAutoScroll } from "./hooks/use-auto-scroll";
2
+ export { useDropdownMenu } from "./hooks/use-dropdown-menu";
3
+ export { useRunCollapseState } from "./hooks/use-run-collapse-state";
4
+ export { useRunGroups } from "./hooks/use-run-groups";
5
+ export type { UseRunGroupsOptions } from "./hooks/use-run-groups";
6
+ export { useSdkSession } from "./hooks/use-sdk-session";
7
+ export type {
8
+ SdkSessionAttachment,
9
+ SdkSessionEvent,
10
+ SdkSessionSeed,
11
+ UseSdkSessionOptions,
12
+ UseSdkSessionReturn,
13
+ BeginAssistantMessageOptions,
14
+ AppendUserMessageOptions,
15
+ CompleteAssistantMessageOptions,
16
+ ApplySdkEventOptions,
17
+ } from "./hooks/use-sdk-session";
18
+ export { useRealtimeSession, RealtimeSessionRegistry } from "./hooks/use-realtime-session";
19
+ export type {
20
+ RealtimeSessionOptions,
21
+ RealtimeSessionState,
22
+ RealtimeSessionTarget,
23
+ RealtimeSessionRegistryProps,
24
+ } from "./hooks/use-realtime-session";
25
+ export { useSSEStream } from "./hooks/use-sse-stream";
26
+ export type {
27
+ SSEEvent,
28
+ ConnectionState,
29
+ UseSSEStreamOptions,
30
+ UseSSEStreamResult,
31
+ TaskStreamEvent,
32
+ AgentStreamEvent,
33
+ TerminalStreamEvent,
34
+ AutomationStreamEvent,
35
+ BotStreamEvent,
36
+ } from "./hooks/use-sse-stream";
37
+ export { useToolCallStream } from "./hooks/use-tool-call-stream";
38
+ export type { UseToolCallStreamReturn } from "./hooks/use-tool-call-stream";