@tangle-network/ui 10.0.0 → 11.1.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.
@@ -6,11 +6,11 @@ import {
6
6
  import {
7
7
  InlineThinkingItem,
8
8
  RunGroup
9
- } from "./chunk-HHYUPAOJ.js";
9
+ } from "./chunk-PX5KV5HI.js";
10
10
  import {
11
11
  ToolCallGroup,
12
12
  ToolCallStep
13
- } from "./chunk-INMWNFAS.js";
13
+ } from "./chunk-4ORVXSMU.js";
14
14
  import {
15
15
  getToolDisplayMetadata
16
16
  } from "./chunk-ULDNFLIM.js";
@@ -103,6 +103,7 @@ var MessageList = memo2(
103
103
  MessageList.displayName = "MessageList";
104
104
 
105
105
  // src/chat/agent-timeline.tsx
106
+ import { useState as useState2 } from "react";
106
107
  import {
107
108
  AlertTriangle,
108
109
  CheckCircle2,
@@ -170,11 +171,12 @@ var TONE_STYLES = {
170
171
  function formatTime2(date) {
171
172
  return date.toLocaleTimeString(void 0, { hour: "numeric", minute: "2-digit" });
172
173
  }
173
- function AgentTimelineRow({ isLast, accentClassName, children }) {
174
+ var CARD_ROW_DOT = "mt-[calc((2.5rem-var(--timeline-dot-size))/2)]";
175
+ function AgentTimelineRow({ isLast, accentClassName, dotClassName = "mt-2", children }) {
174
176
  return /* @__PURE__ */ jsxs3("div", { className: "grid grid-cols-[1.25rem_minmax(0,1fr)] gap-x-4", children: [
175
177
  /* @__PURE__ */ jsxs3("div", { className: "relative flex justify-center", children: [
176
178
  !isLast && /* @__PURE__ */ jsx4("span", { className: "absolute top-4 bottom-[-0.75rem] left-1/2 w-px -translate-x-1/2 bg-border" }),
177
- /* @__PURE__ */ jsx4("span", { className: cn("relative mt-2 h-[var(--timeline-dot-size)] w-[var(--timeline-dot-size)] rounded-full ring-4 ring-[var(--bg-root)]", accentClassName) })
179
+ /* @__PURE__ */ jsx4("span", { className: cn("relative h-[var(--timeline-dot-size)] w-[var(--timeline-dot-size)] rounded-full ring-4 ring-[var(--bg-root)]", dotClassName, accentClassName) })
178
180
  ] }),
179
181
  /* @__PURE__ */ jsx4("div", { className: "min-w-0 pb-3", children })
180
182
  ] });
@@ -233,80 +235,111 @@ function AgentTimeline({
233
235
  isThinking,
234
236
  emptyState,
235
237
  className,
236
- renderToolActions
238
+ renderToolActions,
239
+ collapseAfter
237
240
  }) {
241
+ const [expanded, setExpanded] = useState2(false);
238
242
  if (items.length === 0 && !isThinking) {
239
243
  return emptyState ? /* @__PURE__ */ jsx4("div", { className: cn("flex h-full items-center justify-center p-4", className), children: emptyState }) : null;
240
244
  }
241
245
  const renderedItems = isThinking ? [...items, { id: "__thinking__", kind: "custom", content: /* @__PURE__ */ jsx4(ThinkingIndicator, {}) }] : items;
242
- const timelineItems = renderedItems.filter((item) => !(item.kind === "message" && item.role === "user"));
243
- return /* @__PURE__ */ jsx4("div", { className: cn("mx-auto w-full max-w-5xl px-4 py-4", className), children: renderedItems.map((item, index) => {
244
- if (item.kind === "message" && item.role === "user") {
245
- return /* @__PURE__ */ jsx4("div", { className: "mt-6 mb-4 first:mt-0", children: /* @__PURE__ */ jsx4(UserMessage, { content: item.content, timestamp: item.timestamp }) }, item.id);
246
+ const isUserMessage = (item) => item.kind === "message" && item.role === "user";
247
+ const timelineItems = renderedItems.filter((item) => !isUserMessage(item));
248
+ const limit = collapseAfter ?? Infinity;
249
+ const collapsible = timelineItems.length > limit;
250
+ const collapsed = collapsible && !expanded;
251
+ let renderList = renderedItems;
252
+ let hiddenCount = 0;
253
+ if (collapsed) {
254
+ const visible = [];
255
+ let spineCount = 0;
256
+ for (const item of renderedItems) {
257
+ if (spineCount >= limit) break;
258
+ visible.push(item);
259
+ if (!isUserMessage(item)) spineCount += 1;
246
260
  }
247
- const timelineIndex = timelineItems.indexOf(item);
248
- const isLast = timelineIndex === timelineItems.length - 1;
249
- if (item.kind === "message") {
250
- return /* @__PURE__ */ jsx4(AgentTimelineRow, { isLast, accentClassName: "bg-[var(--brand-glow)]", children: /* @__PURE__ */ jsx4(AssistantMessage, { item }) }, item.id);
251
- }
252
- if (item.kind === "tool") {
253
- return /* @__PURE__ */ jsx4(AgentTimelineRow, { isLast, accentClassName: "bg-[var(--border-hover)]", children: /* @__PURE__ */ jsx4(
254
- ToolCallStep,
255
- {
256
- type: item.call.type,
257
- label: item.call.label,
258
- status: item.call.status,
259
- detail: item.call.detail,
260
- output: item.call.output,
261
- duration: item.call.duration,
262
- part: item.part,
263
- actions: item.part ? renderToolActions?.(item.part) : void 0
264
- }
265
- ) }, item.id);
266
- }
267
- if (item.kind === "tool_group") {
268
- return /* @__PURE__ */ jsx4(AgentTimelineRow, { isLast, accentClassName: "bg-[var(--border-hover)]", children: /* @__PURE__ */ jsx4(ToolCallGroup, { title: item.title, children: item.calls.map((call, callIndex) => {
269
- const part = item.parts?.[callIndex];
270
- return /* @__PURE__ */ jsx4(
261
+ renderList = visible;
262
+ hiddenCount = timelineItems.length - limit;
263
+ }
264
+ const visibleSpine = renderList.filter((item) => !isUserMessage(item));
265
+ const lastSpineItem = collapsible ? void 0 : visibleSpine[visibleSpine.length - 1];
266
+ return /* @__PURE__ */ jsxs3("div", { className: cn("mx-auto w-full max-w-5xl px-4 py-4", className), children: [
267
+ renderList.map((item) => {
268
+ if (item.kind === "message" && item.role === "user") {
269
+ return /* @__PURE__ */ jsx4("div", { className: "mt-6 mb-4 first:mt-0", children: /* @__PURE__ */ jsx4(UserMessage, { content: item.content, timestamp: item.timestamp }) }, item.id);
270
+ }
271
+ const isLast = item === lastSpineItem;
272
+ if (item.kind === "message") {
273
+ return /* @__PURE__ */ jsx4(AgentTimelineRow, { isLast, accentClassName: "bg-[var(--brand-glow)]", children: /* @__PURE__ */ jsx4(AssistantMessage, { item }) }, item.id);
274
+ }
275
+ if (item.kind === "tool") {
276
+ return /* @__PURE__ */ jsx4(AgentTimelineRow, { isLast, accentClassName: "bg-[var(--border-hover)]", dotClassName: CARD_ROW_DOT, children: /* @__PURE__ */ jsx4(
271
277
  ToolCallStep,
272
278
  {
273
- type: call.type,
274
- label: call.label,
275
- status: call.status,
276
- detail: call.detail,
277
- output: call.output,
278
- duration: call.duration,
279
- part,
280
- actions: part ? renderToolActions?.(part) : void 0
279
+ type: item.call.type,
280
+ label: item.call.label,
281
+ status: item.call.status,
282
+ detail: item.call.detail,
283
+ output: item.call.output,
284
+ duration: item.call.duration,
285
+ part: item.part,
286
+ actions: item.part ? renderToolActions?.(item.part) : void 0
287
+ }
288
+ ) }, item.id);
289
+ }
290
+ if (item.kind === "tool_group") {
291
+ return /* @__PURE__ */ jsx4(AgentTimelineRow, { isLast, accentClassName: "bg-[var(--border-hover)]", dotClassName: CARD_ROW_DOT, children: /* @__PURE__ */ jsx4(ToolCallGroup, { title: item.title, children: item.calls.map((call, callIndex) => {
292
+ const part = item.parts?.[callIndex];
293
+ return /* @__PURE__ */ jsx4(
294
+ ToolCallStep,
295
+ {
296
+ type: call.type,
297
+ label: call.label,
298
+ status: call.status,
299
+ detail: call.detail,
300
+ output: call.output,
301
+ duration: call.duration,
302
+ part,
303
+ actions: part ? renderToolActions?.(part) : void 0
304
+ },
305
+ call.id
306
+ );
307
+ }) }) }, item.id);
308
+ }
309
+ if (item.kind === "status") {
310
+ return /* @__PURE__ */ jsx4(
311
+ AgentTimelineRow,
312
+ {
313
+ isLast,
314
+ accentClassName: TONE_STYLES[item.tone ?? "default"].dot,
315
+ children: /* @__PURE__ */ jsx4(StatusCard, { item })
281
316
  },
282
- call.id
317
+ item.id
283
318
  );
284
- }) }) }, item.id);
285
- }
286
- if (item.kind === "status") {
287
- return /* @__PURE__ */ jsx4(
288
- AgentTimelineRow,
289
- {
290
- isLast,
291
- accentClassName: TONE_STYLES[item.tone ?? "default"].dot,
292
- children: /* @__PURE__ */ jsx4(StatusCard, { item })
293
- },
294
- item.id
295
- );
296
- }
297
- if (item.kind === "artifact") {
298
- return /* @__PURE__ */ jsx4(
299
- AgentTimelineRow,
300
- {
301
- isLast,
302
- accentClassName: TONE_STYLES[item.tone ?? "default"].dot,
303
- children: /* @__PURE__ */ jsx4(ArtifactCard, { item })
304
- },
305
- item.id
306
- );
307
- }
308
- return /* @__PURE__ */ jsx4(AgentTimelineRow, { isLast, accentClassName: "bg-[var(--border-hover)]", children: item.content }, item.id);
309
- }) });
319
+ }
320
+ if (item.kind === "artifact") {
321
+ return /* @__PURE__ */ jsx4(
322
+ AgentTimelineRow,
323
+ {
324
+ isLast,
325
+ accentClassName: TONE_STYLES[item.tone ?? "default"].dot,
326
+ children: /* @__PURE__ */ jsx4(ArtifactCard, { item })
327
+ },
328
+ item.id
329
+ );
330
+ }
331
+ return /* @__PURE__ */ jsx4(AgentTimelineRow, { isLast, accentClassName: "bg-[var(--border-hover)]", dotClassName: CARD_ROW_DOT, children: item.content }, item.id);
332
+ }),
333
+ collapsible ? /* @__PURE__ */ jsx4(AgentTimelineRow, { isLast: true, accentClassName: "bg-[var(--border-hover)]", children: /* @__PURE__ */ jsx4(
334
+ "button",
335
+ {
336
+ type: "button",
337
+ onClick: () => setExpanded((value) => !value),
338
+ className: "text-xs font-medium text-muted-foreground transition-colors hover:text-foreground",
339
+ children: collapsed ? `Show ${hiddenCount} more step${hiddenCount === 1 ? "" : "s"}` : "Show less"
340
+ }
341
+ ) }) : null
342
+ ] });
310
343
  }
311
344
 
312
345
  // src/chat/chat-container.tsx
@@ -552,7 +585,8 @@ var ChatContainer = memo3(
552
585
  renderRunActions,
553
586
  renderUserMessageActions,
554
587
  renderToolActions,
555
- renderTimelineToolActions
588
+ renderTimelineToolActions,
589
+ collapseTimelineAfter
556
590
  }) => {
557
591
  const scrollRef = useRef(null);
558
592
  const groups = useRunGroups({ messages, partMap, isStreaming });
@@ -578,7 +612,8 @@ var ChatContainer = memo3(
578
612
  {
579
613
  items: timeline.items,
580
614
  isThinking: timeline.showThinking,
581
- renderToolActions: renderTimelineToolActions
615
+ renderToolActions: renderTimelineToolActions,
616
+ collapseAfter: collapseTimelineAfter
582
617
  }
583
618
  ) }) : /* @__PURE__ */ jsx5("div", { className: "mx-auto flex min-h-full w-full max-w-3xl flex-col justify-end", children: /* @__PURE__ */ jsx5(
584
619
  MessageList,
@@ -1,7 +1,8 @@
1
1
  import {
2
+ ExpandableContent,
2
3
  InlineToolItem,
3
- LiveDuration
4
- } from "./chunk-INMWNFAS.js";
4
+ RunRowShell
5
+ } from "./chunk-4ORVXSMU.js";
5
6
  import {
6
7
  formatDuration,
7
8
  truncateText
@@ -18,9 +19,8 @@ import {
18
19
 
19
20
  // src/run/inline-thinking-item.tsx
20
21
  import { memo, useEffect, useRef, useState } from "react";
21
- import * as Collapsible from "@radix-ui/react-collapsible";
22
- import { Brain, ChevronRight } from "lucide-react";
23
- import { jsx, jsxs } from "react/jsx-runtime";
22
+ import { Brain } from "lucide-react";
23
+ import { jsx } from "react/jsx-runtime";
24
24
  var InlineThinkingItem = memo(
25
25
  ({
26
26
  part,
@@ -33,7 +33,7 @@ var InlineThinkingItem = memo(
33
33
  const autoCollapsedRef = useRef(false);
34
34
  const startTime = part.time?.start;
35
35
  const endTime = part.time?.end;
36
- const durationMs = startTime && endTime ? endTime - startTime : void 0;
36
+ const durationMs = startTime != null && endTime != null ? endTime - startTime : void 0;
37
37
  const isActive = startTime != null && endTime == null;
38
38
  const preview = part.text ? truncateText(part.text, 120) : void 0;
39
39
  useEffect(() => {
@@ -50,72 +50,40 @@ var InlineThinkingItem = memo(
50
50
  return () => window.clearTimeout(timer);
51
51
  }
52
52
  }, [autoCollapse, durationMs, isActive]);
53
- return /* @__PURE__ */ jsx(Collapsible.Root, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxs(
54
- "div",
53
+ return /* @__PURE__ */ jsx(
54
+ RunRowShell,
55
55
  {
56
- className: cn(
57
- "overflow-hidden rounded-[var(--radius-lg)] border bg-card transition-colors",
58
- isActive ? "border-[var(--border-accent)]" : "border-border hover:border-[var(--border-accent)]",
59
- className
60
- ),
61
- children: [
62
- /* @__PURE__ */ jsx(Collapsible.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
63
- "button",
64
- {
65
- className: "flex w-full items-center gap-2.5 px-3 py-2 text-left text-sm cursor-pointer",
66
- children: [
67
- /* @__PURE__ */ jsx(
68
- "div",
69
- {
70
- className: cn(
71
- "flex h-6 w-6 shrink-0 items-center justify-center rounded-[var(--radius-sm)] border",
72
- isActive ? "border-[var(--border-accent)] bg-[var(--accent-surface-soft)] text-primary" : "border-border bg-muted text-muted-foreground"
73
- ),
74
- children: /* @__PURE__ */ jsx(Brain, { className: cn("h-3 w-3 shrink-0", isActive && "animate-pulse") })
75
- }
76
- ),
77
- /* @__PURE__ */ jsx("p", { className: "min-w-0 flex-1 truncate font-[var(--font-sans)] text-muted-foreground", children: preview ?? (isActive ? "Thinking\u2026" : "Reasoning") }),
78
- /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [
79
- isActive && startTime ? /* @__PURE__ */ jsx(LiveDuration, { startTime }) : null,
80
- !isActive && durationMs != null ? /* @__PURE__ */ jsx("span", { className: "shrink-0 text-xs tabular-nums text-muted-foreground", children: formatDuration(durationMs) }) : null,
81
- /* @__PURE__ */ jsx(
82
- ChevronRight,
83
- {
84
- className: cn(
85
- "h-3 w-3 text-muted-foreground transition-transform shrink-0",
86
- open && "rotate-90"
87
- )
88
- }
89
- )
90
- ] })
91
- ]
92
- }
93
- ) }),
94
- /* @__PURE__ */ jsx(Collapsible.Content, { className: "overflow-hidden data-[state=open]:animate-slideDown data-[state=closed]:animate-slideUp", children: part.text ? /* @__PURE__ */ jsx(
95
- "div",
96
- {
97
- className: cn(
98
- "max-h-60 overflow-y-auto border-t border-border bg-muted px-3 py-3 text-sm leading-relaxed text-muted-foreground",
99
- contentClassName
100
- ),
101
- children: /* @__PURE__ */ jsx(Markdown, { children: part.text })
102
- }
103
- ) : /* @__PURE__ */ jsx("div", { className: "border-t border-border bg-muted px-3 py-2.5 text-xs text-muted-foreground", children: "No reasoning text provided." }) })
104
- ]
56
+ icon: /* @__PURE__ */ jsx(Brain, { className: "h-3.5 w-3.5" }),
57
+ title: isActive ? "Thinking\u2026" : "Reasoning",
58
+ description: preview,
59
+ status: isActive ? "running" : "idle",
60
+ startTime,
61
+ durationMs,
62
+ open,
63
+ onOpenChange: setOpen,
64
+ className,
65
+ children: part.text ? /* @__PURE__ */ jsx(
66
+ ExpandableContent,
67
+ {
68
+ fadeClassName: "from-[var(--md3-surface-container)]",
69
+ className: contentClassName ? `px-3 py-3 ${contentClassName}` : "px-3 py-3",
70
+ children: /* @__PURE__ */ jsx("div", { className: "text-sm leading-relaxed text-foreground", children: /* @__PURE__ */ jsx(Markdown, { children: part.text }) })
71
+ }
72
+ ) : /* @__PURE__ */ jsx("div", { className: "px-3 py-2.5 text-xs text-muted-foreground", children: "No reasoning text provided." })
105
73
  }
106
- ) });
74
+ );
107
75
  }
108
76
  );
109
77
  InlineThinkingItem.displayName = "InlineThinkingItem";
110
78
 
111
79
  // src/run/run-group.tsx
112
80
  import { memo as memo2, useMemo } from "react";
113
- import * as Collapsible2 from "@radix-ui/react-collapsible";
81
+ import * as Collapsible from "@radix-ui/react-collapsible";
114
82
  import {
115
83
  Bot,
116
84
  Loader2,
117
85
  ChevronDown,
118
- ChevronRight as ChevronRight2,
86
+ ChevronRight,
119
87
  Terminal,
120
88
  FileEdit,
121
89
  FileSearch,
@@ -126,14 +94,14 @@ import {
126
94
  Settings,
127
95
  Sparkles
128
96
  } from "lucide-react";
129
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
97
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
130
98
  function SpineRow({
131
99
  accentClassName,
132
100
  isLast,
133
101
  children
134
102
  }) {
135
- return /* @__PURE__ */ jsxs2("div", { className: "grid grid-cols-[1.25rem_minmax(0,1fr)] gap-x-3", children: [
136
- /* @__PURE__ */ jsxs2("div", { className: "relative flex justify-center", children: [
103
+ return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[1.25rem_minmax(0,1fr)] gap-x-3", children: [
104
+ /* @__PURE__ */ jsxs("div", { className: "relative flex justify-center", children: [
137
105
  !isLast && /* @__PURE__ */ jsx2("span", { className: "absolute top-3.5 bottom-[-0.75rem] left-1/2 w-px -translate-x-1/2 bg-[var(--border-subtle)]" }),
138
106
  /* @__PURE__ */ jsx2(
139
107
  "span",
@@ -163,10 +131,10 @@ function AssistantShell({
163
131
  isStreaming,
164
132
  children
165
133
  }) {
166
- return /* @__PURE__ */ jsxs2("div", { className: "flex flex-col gap-1", children: [
167
- /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2 px-1 font-medium text-muted-foreground text-xs", children: [
134
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
135
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-1 font-medium text-muted-foreground text-xs", children: [
168
136
  /* @__PURE__ */ jsx2("span", { children: branding.label }),
169
- isStreaming ? /* @__PURE__ */ jsxs2("span", { className: "inline-flex items-center gap-1.5", children: [
137
+ isStreaming ? /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5", children: [
170
138
  /* @__PURE__ */ jsx2(Loader2, { className: "h-3 w-3 animate-spin" }),
171
139
  "Thinking"
172
140
  ] }) : null
@@ -321,7 +289,7 @@ var RunGroup = memo2(
321
289
  if (!isStreaming) {
322
290
  return null;
323
291
  }
324
- return /* @__PURE__ */ jsx2(AssistantShell, { branding, isStreaming: true, children: /* @__PURE__ */ jsx2("div", { className: "flex items-center gap-2 px-0.5 py-0.5 text-sm text-[var(--text-muted)]", children: /* @__PURE__ */ jsxs2("span", { className: "flex gap-[5px]", children: [
292
+ return /* @__PURE__ */ jsx2(AssistantShell, { branding, isStreaming: true, children: /* @__PURE__ */ jsx2("div", { className: "flex items-center gap-2 px-0.5 py-0.5 text-sm text-[var(--text-muted)]", children: /* @__PURE__ */ jsxs("span", { className: "flex gap-[5px]", children: [
325
293
  /* @__PURE__ */ jsx2("span", { className: "h-2 w-2 animate-bounce rounded-full bg-[var(--brand-glow)]", style: { animationDelay: "0ms" } }),
326
294
  /* @__PURE__ */ jsx2("span", { className: "h-2 w-2 animate-bounce rounded-full bg-[var(--brand-glow)]", style: { animationDelay: "150ms" } }),
327
295
  /* @__PURE__ */ jsx2("span", { className: "h-2 w-2 animate-bounce rounded-full bg-[var(--brand-glow)]", style: { animationDelay: "300ms" } })
@@ -344,7 +312,7 @@ var RunGroup = memo2(
344
312
  const schema = extractOpenUISchema(toolPart.state.output);
345
313
  const summary = getOpenUISummary(toolPart.state.output);
346
314
  if (toolPart.state.status === "completed" && schema) {
347
- return /* @__PURE__ */ jsxs2(
315
+ return /* @__PURE__ */ jsxs(
348
316
  "div",
349
317
  {
350
318
  className: "overflow-hidden rounded-[var(--radius-lg)] border border-[var(--border-subtle)] bg-[var(--md3-surface-container)]",
@@ -357,7 +325,7 @@ var RunGroup = memo2(
357
325
  );
358
326
  }
359
327
  if (toolPart.state.status === "running") {
360
- return /* @__PURE__ */ jsxs2(
328
+ return /* @__PURE__ */ jsxs(
361
329
  "div",
362
330
  {
363
331
  className: "flex items-center gap-2 rounded-[var(--radius-lg)] border border-[var(--border-subtle)] bg-[var(--md3-surface-container)] px-4 py-3 text-sm text-muted-foreground",
@@ -385,24 +353,24 @@ var RunGroup = memo2(
385
353
  if (part.type === "text") return "bg-primary";
386
354
  return "bg-[var(--border-hover)]";
387
355
  };
388
- return /* @__PURE__ */ jsx2(Collapsible2.Root, { open: !collapsed, onOpenChange: () => onToggle(), children: /* @__PURE__ */ jsxs2("div", { className: "flex flex-col gap-1", children: [
389
- /* @__PURE__ */ jsxs2("div", { className: "flex items-start gap-2", children: [
390
- /* @__PURE__ */ jsx2(Collapsible2.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs2(
356
+ return /* @__PURE__ */ jsx2(Collapsible.Root, { open: !collapsed, onOpenChange: () => onToggle(), children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
357
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
358
+ /* @__PURE__ */ jsx2(Collapsible.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
391
359
  "button",
392
360
  {
393
361
  type: "button",
394
362
  className: "group flex min-w-0 flex-1 items-center gap-2 rounded-md px-1 py-0.5 text-left transition-colors hover:bg-[var(--surface-container-high)]/40",
395
363
  children: [
396
- collapsed ? /* @__PURE__ */ jsx2(ChevronRight2, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }) : /* @__PURE__ */ jsx2(ChevronDown, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
364
+ collapsed ? /* @__PURE__ */ jsx2(ChevronRight, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }) : /* @__PURE__ */ jsx2(ChevronDown, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
397
365
  /* @__PURE__ */ jsx2("span", { className: cn("font-semibold text-sm", branding.textClass), children: branding.label }),
398
366
  renderSummary(run) ? /* @__PURE__ */ jsx2("span", { className: "text-[11px] text-muted-foreground", children: renderSummary(run) }) : null,
399
367
  collapsed && run.summaryText ? /* @__PURE__ */ jsx2("span", { className: "min-w-0 truncate text-[11px] text-foreground/70", children: run.summaryText }) : null,
400
- /* @__PURE__ */ jsxs2("span", { className: "ml-auto flex shrink-0 items-center gap-1.5", children: [
368
+ /* @__PURE__ */ jsxs("span", { className: "ml-auto flex shrink-0 items-center gap-1.5", children: [
401
369
  /* @__PURE__ */ jsx2(CategoryBadges, { categories: stats.toolCategories }),
402
- isStreaming ? /* @__PURE__ */ jsxs2("span", { className: "inline-flex items-center gap-1 rounded-full border border-[var(--border-accent)] bg-[var(--accent-surface-soft)] px-2 py-px text-[10px] font-semibold uppercase text-[var(--accent-text)]", children: [
370
+ isStreaming ? /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 rounded-full border border-[var(--border-accent)] bg-[var(--accent-surface-soft)] px-2 py-px text-[10px] font-semibold uppercase text-[var(--accent-text)]", children: [
403
371
  /* @__PURE__ */ jsx2(Loader2, { className: "h-2.5 w-2.5 animate-spin" }),
404
372
  "Running"
405
- ] }) : /* @__PURE__ */ jsxs2("span", { className: "inline-flex items-center gap-1 rounded-full border border-border px-2 py-px text-[10px] font-semibold uppercase text-muted-foreground", children: [
373
+ ] }) : /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 rounded-full border border-border px-2 py-px text-[10px] font-semibold uppercase text-muted-foreground", children: [
406
374
  /* @__PURE__ */ jsx2(Sparkles, { className: "h-2.5 w-2.5" }),
407
375
  "Done"
408
376
  ] })
@@ -413,7 +381,7 @@ var RunGroup = memo2(
413
381
  headerActions ? /* @__PURE__ */ jsx2("div", { className: "flex shrink-0 flex-wrap items-center justify-end gap-1.5 pt-1", children: headerActions }) : null
414
382
  ] }),
415
383
  collapsed && run.summaryText ? /* @__PURE__ */ jsx2("div", { className: "line-clamp-2 pl-6 text-sm leading-6 text-muted-foreground", children: run.summaryText }) : null,
416
- /* @__PURE__ */ jsx2(Collapsible2.Content, { className: "overflow-hidden data-[state=open]:animate-slideDown data-[state=closed]:animate-slideUp", children: /* @__PURE__ */ jsx2("div", { className: "pt-1.5", children: rows.map(({ part, msgId, index }, rowIndex) => {
384
+ /* @__PURE__ */ jsx2(Collapsible.Content, { className: "overflow-hidden data-[state=open]:animate-slideDown data-[state=closed]:animate-slideUp", children: /* @__PURE__ */ jsx2("div", { className: "pt-1.5", children: rows.map(({ part, msgId, index }, rowIndex) => {
417
385
  const key = `${msgId}-${index}`;
418
386
  const isLast = rowIndex === rows.length - 1;
419
387
  let node = null;
@@ -423,12 +391,12 @@ var RunGroup = memo2(
423
391
  const schema = extractOpenUISchema(toolPart.state.output);
424
392
  const summary = getOpenUISummary(toolPart.state.output);
425
393
  if (toolPart.state.status === "completed" && schema) {
426
- node = /* @__PURE__ */ jsxs2("div", { className: "overflow-hidden rounded-[var(--radius-lg)] border border-[var(--border-subtle)] bg-[var(--md3-surface-container)]", children: [
394
+ node = /* @__PURE__ */ jsxs("div", { className: "overflow-hidden rounded-[var(--radius-lg)] border border-[var(--border-subtle)] bg-[var(--md3-surface-container)]", children: [
427
395
  summary ? /* @__PURE__ */ jsx2("div", { className: "border-b border-[var(--border-subtle)] px-4 py-3 text-sm leading-6 text-foreground", children: summary }) : null,
428
396
  /* @__PURE__ */ jsx2("div", { className: "p-4", children: /* @__PURE__ */ jsx2(OpenUIArtifactRenderer, { schema }) })
429
397
  ] });
430
398
  } else if (toolPart.state.status === "running") {
431
- node = /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-3 rounded-[var(--radius-lg)] border border-[var(--border-subtle)] bg-[var(--md3-surface-container)] px-4 py-3 text-sm text-muted-foreground", children: [
399
+ node = /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 rounded-[var(--radius-lg)] border border-[var(--border-subtle)] bg-[var(--md3-surface-container)] px-4 py-3 text-sm text-muted-foreground", children: [
432
400
  /* @__PURE__ */ jsx2(Loader2, { className: "h-4 w-4 animate-spin text-primary" }),
433
401
  "Building view\u2026"
434
402
  ] });
package/dist/hooks.js CHANGED
@@ -11,15 +11,15 @@ import {
11
11
  useSSEStream,
12
12
  useSdkSession,
13
13
  useToolCallStream
14
- } from "./chunk-CCM2KRQH.js";
14
+ } from "./chunk-EWIWYC2I.js";
15
15
  import "./chunk-OEX7NZE3.js";
16
16
  import {
17
17
  useAutoScroll,
18
18
  useRunCollapseState,
19
19
  useRunGroups
20
20
  } from "./chunk-AZWDI2JG.js";
21
- import "./chunk-KBOD47AW.js";
22
- import "./chunk-INMWNFAS.js";
21
+ import "./chunk-F22SQTBP.js";
22
+ import "./chunk-4ORVXSMU.js";
23
23
  import "./chunk-ULDNFLIM.js";
24
24
  import "./chunk-AAUNOHVL.js";
25
25
  import "./chunk-ZRVH3WCA.js";
package/dist/index.js CHANGED
@@ -17,7 +17,7 @@ import {
17
17
  useSSEStream,
18
18
  useSdkSession,
19
19
  useToolCallStream
20
- } from "./chunk-CCM2KRQH.js";
20
+ } from "./chunk-EWIWYC2I.js";
21
21
  import {
22
22
  addMessage,
23
23
  addParts,
@@ -137,7 +137,7 @@ import {
137
137
  MessageList,
138
138
  ThinkingIndicator,
139
139
  UserMessage
140
- } from "./chunk-KHO7DYXH.js";
140
+ } from "./chunk-FIFE5HCW.js";
141
141
  import {
142
142
  useAutoScroll,
143
143
  useRunCollapseState,
@@ -147,16 +147,16 @@ import "./chunk-47XH56SV.js";
147
147
  import {
148
148
  ToolCallFeed,
149
149
  parseToolEvent
150
- } from "./chunk-KBOD47AW.js";
150
+ } from "./chunk-F22SQTBP.js";
151
151
  import {
152
152
  InlineThinkingItem,
153
153
  RunGroup
154
- } from "./chunk-HHYUPAOJ.js";
154
+ } from "./chunk-PX5KV5HI.js";
155
155
  import {
156
156
  ExpandedToolDetail,
157
157
  InlineToolItem,
158
158
  LiveDuration
159
- } from "./chunk-INMWNFAS.js";
159
+ } from "./chunk-4ORVXSMU.js";
160
160
  import {
161
161
  TOOL_CATEGORY_ICONS,
162
162
  formatBytes,
package/dist/run.d.ts CHANGED
@@ -41,9 +41,10 @@ interface InlineToolItemProps {
41
41
  description?: string;
42
42
  }
43
43
  /**
44
- * Compact single-line tool call display (32px height).
45
- * Shows icon, title, description, duration, and status indicator.
46
- * Expands on click to show ExpandedToolDetail.
44
+ * Compact single-line tool call display. Shows a category icon, title,
45
+ * description, duration and status, and expands on click to show
46
+ * ExpandedToolDetail. Rendered through the shared RunRowShell so it stays
47
+ * consistent with the reasoning row.
47
48
  */
48
49
  declare const InlineToolItem: React.MemoExoticComponent<({ part, renderToolDetail, groupPosition, className, contentClassName, actions, title: titleOverride, description: descriptionOverride, }: InlineToolItemProps) => react_jsx_runtime.JSX.Element>;
49
50
 
package/dist/run.js CHANGED
@@ -2,16 +2,16 @@ import "./chunk-47XH56SV.js";
2
2
  import {
3
3
  ToolCallFeed,
4
4
  parseToolEvent
5
- } from "./chunk-KBOD47AW.js";
5
+ } from "./chunk-F22SQTBP.js";
6
6
  import {
7
7
  InlineThinkingItem,
8
8
  RunGroup
9
- } from "./chunk-HHYUPAOJ.js";
9
+ } from "./chunk-PX5KV5HI.js";
10
10
  import {
11
11
  ExpandedToolDetail,
12
12
  InlineToolItem,
13
13
  LiveDuration
14
- } from "./chunk-INMWNFAS.js";
14
+ } from "./chunk-4ORVXSMU.js";
15
15
  import "./chunk-ULDNFLIM.js";
16
16
  import "./chunk-AAUNOHVL.js";
17
17
  import "./chunk-52Y3FMFI.js";
package/dist/sdk-hooks.js CHANGED
@@ -5,15 +5,15 @@ import {
5
5
  useSSEStream,
6
6
  useSdkSession,
7
7
  useToolCallStream
8
- } from "./chunk-CCM2KRQH.js";
8
+ } from "./chunk-EWIWYC2I.js";
9
9
  import "./chunk-OEX7NZE3.js";
10
10
  import {
11
11
  useAutoScroll,
12
12
  useRunCollapseState,
13
13
  useRunGroups
14
14
  } from "./chunk-AZWDI2JG.js";
15
- import "./chunk-KBOD47AW.js";
16
- import "./chunk-INMWNFAS.js";
15
+ import "./chunk-F22SQTBP.js";
16
+ import "./chunk-4ORVXSMU.js";
17
17
  import "./chunk-ULDNFLIM.js";
18
18
  import "./chunk-AAUNOHVL.js";
19
19
  import "./chunk-ZRVH3WCA.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/ui",
3
- "version": "10.0.0",
3
+ "version": "11.1.0",
4
4
  "description": "Generic React UI components for Tangle products — primitives, chat, run, files, editor, markdown.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -132,7 +132,7 @@
132
132
  "react": "^18 || ^19",
133
133
  "react-dom": "^18 || ^19",
134
134
  "react-router": "^7",
135
- "@tangle-network/brand": "^0.9.0"
135
+ "@tangle-network/brand": "^1.0.0"
136
136
  },
137
137
  "peerDependenciesMeta": {
138
138
  "@nanostores/react": {
@@ -164,6 +164,17 @@ export const CodingSession: Story = {
164
164
  },
165
165
  }
166
166
 
167
+ // ---------------------------------------------------------------------------
168
+ // Long session collapsed to the first N spine rows behind a toggle
169
+ // ---------------------------------------------------------------------------
170
+
171
+ export const Collapsed: Story = {
172
+ args: {
173
+ items: codingSession,
174
+ collapseAfter: 3,
175
+ },
176
+ }
177
+
167
178
  // ---------------------------------------------------------------------------
168
179
  // Session with thinking indicator active
169
180
  // ---------------------------------------------------------------------------