@tangle-network/ui 11.48.0 → 11.50.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.
- package/CHANGELOG.md +28 -0
- package/dist/chat/agent-timeline.js +4 -3
- package/dist/chat/speaker.d.ts +3 -3
- package/dist/chat/speaker.js +12 -18
- package/dist/index.d.ts +4 -3
- package/dist/index.js +4 -3
- package/dist/markdown/code-block.js +1 -1
- package/dist/presentation.d.ts +12 -0
- package/dist/presentation.js +85 -1
- package/dist/primitives/metric-strip.d.ts +2 -2
- package/dist/primitives/page-shell.d.ts +6 -3
- package/dist/primitives/page-shell.js +3 -60
- package/dist/primitives/progress.d.ts +8 -0
- package/dist/primitives/progress.js +8 -2
- package/dist/primitives/settings.d.ts +28 -1
- package/dist/primitives/settings.js +78 -29
- package/dist/primitives/status-pill.js +11 -2
- package/dist/primitives.d.ts +3 -3
- package/dist/primitives.js +3 -3
- package/dist/run/expanded-tool-detail.js +12 -4
- package/dist/run/run-group.js +21 -9
- package/dist/run/run-phase-list.js +5 -8
- package/dist/run/status-meta.d.ts +25 -0
- package/dist/run/status-meta.js +105 -0
- package/dist/run.d.ts +2 -1
- package/dist/run.js +2 -1
- package/package.json +2 -2
- package/src/chat/agent-timeline.test.tsx +9 -0
- package/src/chat/agent-timeline.tsx +4 -3
- package/src/chat/speaker.test.tsx +3 -1
- package/src/chat/speaker.tsx +13 -14
- package/src/markdown/code-block.tsx +2 -1
- package/src/markdown/markdown.stories.tsx +11 -0
- package/src/presentation.ts +68 -0
- package/src/primitives/index.ts +2 -1
- package/src/primitives/metric-strip.tsx +2 -2
- package/src/primitives/page-shell.tsx +9 -58
- package/src/primitives/progress.stories.tsx +10 -0
- package/src/primitives/progress.tsx +13 -2
- package/src/primitives/settings.stories.tsx +94 -3
- package/src/primitives/settings.tsx +80 -19
- package/src/primitives/status-pill.tsx +8 -1
- package/src/run/expanded-tool-detail.tsx +4 -10
- package/src/run/index.ts +8 -0
- package/src/run/run-group.tsx +8 -16
- package/src/run/run-phase-list.stories.tsx +19 -0
- package/src/run/run-phase-list.test.tsx +9 -1
- package/src/run/run-phase-list.tsx +3 -3
- package/src/run/status-meta.tsx +92 -0
- package/src/styles/presentation.css +3 -3
|
@@ -6,19 +6,20 @@ import { Label } from "./label.js";
|
|
|
6
6
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "./dropdown-menu.js";
|
|
7
7
|
import { InfoTip } from "./info-tip.js";
|
|
8
8
|
import { fieldMessageId } from "./field.js";
|
|
9
|
+
import { StatusGlyph } from "./status-pill.js";
|
|
9
10
|
import * as React from "react";
|
|
10
11
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
-
import { CircleAlert, Ellipsis, Lock } from "lucide-react";
|
|
12
|
+
import { CircleAlert, Ellipsis, Lock, TriangleAlert } from "lucide-react";
|
|
12
13
|
// src/primitives/settings.tsx
|
|
13
14
|
const SCROLL_OFFSET = "scroll-mt-[calc(var(--shell-header-height)_+_1rem)]";
|
|
15
|
+
const GUTTER = "px-5 py-4 @max-[34rem]/settings-section:px-4";
|
|
14
16
|
const DIVIDED = "not-first:border-t not-first:border-[color:var(--border-subtle)]";
|
|
15
17
|
const ERROR_TEXT = "text-[color:var(--surface-danger-text)]";
|
|
16
|
-
function
|
|
18
|
+
function GlyphLine({ icon: Icon, className, children, ...props }) {
|
|
17
19
|
return /* @__PURE__ */ jsxs("div", {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
children: [/* @__PURE__ */ jsx(CircleAlert, {
|
|
20
|
+
...props,
|
|
21
|
+
className: cn("flex items-start gap-1.5 text-sm leading-5 [overflow-wrap:anywhere]", className),
|
|
22
|
+
children: [/* @__PURE__ */ jsx(Icon, {
|
|
22
23
|
"aria-hidden": "true",
|
|
23
24
|
className: "mt-0.5 size-4 shrink-0"
|
|
24
25
|
}), /* @__PURE__ */ jsx("div", {
|
|
@@ -27,18 +28,32 @@ function ErrorLine({ id, className, children }) {
|
|
|
27
28
|
})]
|
|
28
29
|
});
|
|
29
30
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
31
|
+
const ErrorLine = ({ className, ...props }) => /* @__PURE__ */ jsx(GlyphLine, {
|
|
32
|
+
icon: CircleAlert,
|
|
33
|
+
role: "alert",
|
|
34
|
+
className: cn(ERROR_TEXT, className),
|
|
35
|
+
...props
|
|
36
|
+
});
|
|
37
|
+
const LockLine = ({ className, ...props }) => /* @__PURE__ */ jsx(GlyphLine, {
|
|
38
|
+
icon: Lock,
|
|
39
|
+
className: cn("text-muted-foreground", className),
|
|
40
|
+
...props
|
|
41
|
+
});
|
|
42
|
+
const TOKEN_BREAK = /(?<=[/@])(?=[^/])|(?<=[\p{L}\p{N}])(?=[.\-_?#&=][\p{L}\p{N}])/u;
|
|
43
|
+
function breakTokens(node) {
|
|
44
|
+
if (typeof node === "string") {
|
|
45
|
+
if (!TOKEN_BREAK.test(node)) return node;
|
|
46
|
+
return node.split(/(\s+)/).map((word, index) => {
|
|
47
|
+
const parts = word.split(TOKEN_BREAK);
|
|
48
|
+
return parts.length < 2 ? word : /* @__PURE__ */ jsx("span", {
|
|
49
|
+
className: "inline-block max-w-full [text-decoration:inherit]",
|
|
50
|
+
children: parts.map((part, at) => /* @__PURE__ */ jsxs(React.Fragment, { children: [at > 0 && /* @__PURE__ */ jsx("wbr", {}), part] }, at))
|
|
51
|
+
}, index);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
if (Array.isArray(node)) return React.Children.map(node, breakTokens);
|
|
55
|
+
if (React.isValidElement(node) && node.props.children != null && typeof node.props.children !== "function") return React.cloneElement(node, void 0, breakTokens(node.props.children));
|
|
56
|
+
return node;
|
|
42
57
|
}
|
|
43
58
|
const ROW_COLUMNS = {
|
|
44
59
|
inline: "grid-cols-[minmax(0,1fr)_minmax(13rem,20rem)] @max-[34rem]/settings-section:grid-cols-1",
|
|
@@ -73,7 +88,7 @@ function SettingsRow(props) {
|
|
|
73
88
|
return /* @__PURE__ */ jsxs("div", {
|
|
74
89
|
id,
|
|
75
90
|
"data-layout": layout,
|
|
76
|
-
className: cn("grid min-w-0 items-center gap-x-8 gap-y-3
|
|
91
|
+
className: cn("grid min-w-0 items-center gap-x-8 gap-y-3", GUTTER, SCROLL_OFFSET, DIVIDED, ROW_COLUMNS[hasValue && layout === "compact" ? "inline" : layout]),
|
|
77
92
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
78
93
|
className: "min-w-0",
|
|
79
94
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
@@ -121,7 +136,7 @@ function SettingsRow(props) {
|
|
|
121
136
|
children: [hasValue && /* @__PURE__ */ jsx("span", {
|
|
122
137
|
"data-slot": "settings-value",
|
|
123
138
|
className: cn("min-w-0 text-foreground text-sm [overflow-wrap:anywhere] @min-[34rem]/settings-section:text-right", mono && "font-mono"),
|
|
124
|
-
children: value
|
|
139
|
+
children: breakTokens(value)
|
|
125
140
|
}), control]
|
|
126
141
|
})]
|
|
127
142
|
});
|
|
@@ -142,7 +157,7 @@ function SettingsSection({ id, title, description, info, actions, tone = "defaul
|
|
|
142
157
|
className: cn("@container/settings-section min-w-0", SCROLL_OFFSET, danger && "border-[color:var(--surface-danger-border)]"),
|
|
143
158
|
children: [
|
|
144
159
|
/* @__PURE__ */ jsxs("div", {
|
|
145
|
-
className: "flex items-start justify-between gap-4
|
|
160
|
+
className: cn("flex items-start justify-between gap-4 @max-[34rem]/settings-section:flex-wrap", GUTTER),
|
|
146
161
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
147
162
|
className: "min-w-0",
|
|
148
163
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
@@ -173,6 +188,35 @@ function SettingsSection({ id, title, description, info, actions, tone = "defaul
|
|
|
173
188
|
]
|
|
174
189
|
});
|
|
175
190
|
}
|
|
191
|
+
const NOTE_TONE = {
|
|
192
|
+
default: "text-foreground",
|
|
193
|
+
muted: "text-muted-foreground",
|
|
194
|
+
warning: "text-[color:var(--surface-warning-text)]",
|
|
195
|
+
danger: ERROR_TEXT
|
|
196
|
+
};
|
|
197
|
+
const NOTE_GLYPH = {
|
|
198
|
+
warning: TriangleAlert,
|
|
199
|
+
danger: CircleAlert
|
|
200
|
+
};
|
|
201
|
+
/**
|
|
202
|
+
* A line or block of a {@link SettingsSection} that is not a row: an empty list, a loading line,
|
|
203
|
+
* a notice, a refusal or a figure. It takes the rows' gutters and divider, so it lines up with
|
|
204
|
+
* the rows and lists around it.
|
|
205
|
+
*/
|
|
206
|
+
function SettingsNote({ tone = "default", role, children }) {
|
|
207
|
+
const className = cn("min-w-0", GUTTER, DIVIDED, NOTE_TONE[tone]);
|
|
208
|
+
const glyph = NOTE_GLYPH[tone];
|
|
209
|
+
return glyph ? /* @__PURE__ */ jsx(GlyphLine, {
|
|
210
|
+
icon: glyph,
|
|
211
|
+
role,
|
|
212
|
+
className,
|
|
213
|
+
children
|
|
214
|
+
}) : /* @__PURE__ */ jsx("div", {
|
|
215
|
+
role,
|
|
216
|
+
className: cn("text-sm leading-5 [overflow-wrap:anywhere]", className),
|
|
217
|
+
children
|
|
218
|
+
});
|
|
219
|
+
}
|
|
176
220
|
const LIST_SLOTS = [
|
|
177
221
|
"leading",
|
|
178
222
|
"main",
|
|
@@ -251,7 +295,7 @@ const NARROW_STATUS = "@max-[34rem]/settings-section:col-start-[main] @max-[34re
|
|
|
251
295
|
* that name. Without a status column the state follows the meta, and without
|
|
252
296
|
* a menu column the ⋯ menu ends the action cell.
|
|
253
297
|
*/
|
|
254
|
-
function SettingsListItem({ leading, title, meta, status, error, action, menu }) {
|
|
298
|
+
function SettingsListItem({ leading, title, meta, status, tone, error, action, menu }) {
|
|
255
299
|
const columns = React.useContext(SettingsListContext);
|
|
256
300
|
const titleId = React.useId();
|
|
257
301
|
const reasonId = `${titleId}-reason`;
|
|
@@ -268,6 +312,11 @@ function SettingsListItem({ leading, title, meta, status, error, action, menu })
|
|
|
268
312
|
onClick: locked ? void 0 : action.onSelect,
|
|
269
313
|
children: action.label
|
|
270
314
|
});
|
|
315
|
+
const state = tone && status != null ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(StatusGlyph, { tone }), /* @__PURE__ */ jsx("span", {
|
|
316
|
+
className: "min-w-0",
|
|
317
|
+
children: status
|
|
318
|
+
})] }) : status;
|
|
319
|
+
const toned = tone && "flex items-center gap-1.5";
|
|
271
320
|
const actionCell = (actionButton || menuNode && !columns.menu) && /* @__PURE__ */ jsxs(Fragment$1, { children: [actionButton, !columns.menu && menuNode] });
|
|
272
321
|
return /* @__PURE__ */ jsxs("li", {
|
|
273
322
|
className: cn("col-span-full grid grid-cols-subgrid items-center px-5 py-3 @max-[34rem]/settings-section:px-4", DIVIDED),
|
|
@@ -282,15 +331,15 @@ function SettingsListItem({ leading, title, meta, status, error, action, menu })
|
|
|
282
331
|
/* @__PURE__ */ jsx("div", {
|
|
283
332
|
id: titleId,
|
|
284
333
|
className: "font-medium text-sm leading-5 text-foreground [overflow-wrap:anywhere] [&_a]:rounded-sm [&_a]:text-foreground [&_a]:underline-offset-4 [&_a:hover]:underline [&_a:focus-visible]:outline-2 [&_a:focus-visible]:outline-offset-2 [&_a:focus-visible]:outline-[var(--focus-border)]",
|
|
285
|
-
children: title
|
|
334
|
+
children: breakTokens(title)
|
|
286
335
|
}),
|
|
287
336
|
meta != null && /* @__PURE__ */ jsx("div", {
|
|
288
337
|
className: "text-sm leading-5 text-muted-foreground [overflow-wrap:anywhere]",
|
|
289
|
-
children: meta
|
|
338
|
+
children: breakTokens(meta)
|
|
290
339
|
}),
|
|
291
340
|
status != null && !columns.status && /* @__PURE__ */ jsx("div", {
|
|
292
|
-
className: "mt-1 text-sm leading-5 text-muted-foreground",
|
|
293
|
-
children:
|
|
341
|
+
className: cn("mt-1 text-sm leading-5 text-muted-foreground", toned),
|
|
342
|
+
children: state
|
|
294
343
|
}),
|
|
295
344
|
locked && /* @__PURE__ */ jsx(LockLine, {
|
|
296
345
|
id: reasonId,
|
|
@@ -304,8 +353,8 @@ function SettingsListItem({ leading, title, meta, status, error, action, menu })
|
|
|
304
353
|
children: error
|
|
305
354
|
}),
|
|
306
355
|
status != null && columns.status && /* @__PURE__ */ jsx("div", {
|
|
307
|
-
className: cn("col-start-[status] row-start-1 min-w-0 text-sm leading-5 text-muted-foreground", NARROW_STATUS),
|
|
308
|
-
children:
|
|
356
|
+
className: cn("col-start-[status] row-start-1 min-w-0 text-sm leading-5 text-muted-foreground", toned, NARROW_STATUS),
|
|
357
|
+
children: state
|
|
309
358
|
}),
|
|
310
359
|
actionCell && /* @__PURE__ */ jsx("div", {
|
|
311
360
|
className: "col-start-[action] row-start-1 flex min-w-0 items-center justify-end gap-1",
|
|
@@ -318,4 +367,4 @@ function SettingsListItem({ leading, title, meta, status, error, action, menu })
|
|
|
318
367
|
]
|
|
319
368
|
});
|
|
320
369
|
}
|
|
321
|
-
export { SettingsList, SettingsListItem, SettingsRow, SettingsSection };
|
|
370
|
+
export { SettingsList, SettingsListItem, SettingsNote, SettingsRow, SettingsSection };
|
|
@@ -107,15 +107,24 @@ function ToneGlyph({ tone }) {
|
|
|
107
107
|
});
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
|
+
const GLYPH = "inline-flex [&>svg]:size-3 [&>svg]:shrink-0";
|
|
111
|
+
/** The tone's glyph in the tone's ink, before a label that keeps its own colour, as `bare` draws it. */
|
|
112
|
+
function StatusGlyph({ tone }) {
|
|
113
|
+
return /* @__PURE__ */ jsx("span", {
|
|
114
|
+
"aria-hidden": "true",
|
|
115
|
+
className: cn(GLYPH, TONE_TEXT[tone]),
|
|
116
|
+
children: /* @__PURE__ */ jsx(ToneGlyph, { tone })
|
|
117
|
+
});
|
|
118
|
+
}
|
|
110
119
|
const StatusPill = React.forwardRef(({ className, tone, children, icon, bare = false, size = "sm", ...props }, ref) => /* @__PURE__ */ jsxs("span", {
|
|
111
120
|
ref,
|
|
112
121
|
className: cn("inline-flex items-center gap-1.5 whitespace-nowrap rounded-full font-medium", size === "sm" ? "px-2 py-0.5 text-xs" : "px-2.5 py-1 text-sm", bare ? "border border-transparent bg-transparent px-0" : cn("border", TONE_SURFACE[tone]), className),
|
|
113
122
|
...props,
|
|
114
123
|
children: [/* @__PURE__ */ jsx("span", {
|
|
115
124
|
"aria-hidden": "true",
|
|
116
|
-
className: cn(
|
|
125
|
+
className: cn(GLYPH, bare && TONE_TEXT[tone]),
|
|
117
126
|
children: icon ?? /* @__PURE__ */ jsx(ToneGlyph, { tone })
|
|
118
127
|
}), children]
|
|
119
128
|
}));
|
|
120
129
|
StatusPill.displayName = "StatusPill";
|
|
121
|
-
export { StatusPill };
|
|
130
|
+
export { StatusGlyph, StatusPill };
|
package/dist/primitives.d.ts
CHANGED
|
@@ -45,11 +45,11 @@ import { ThemeToggle, useTheme } from "./primitives/theme-toggle.js";
|
|
|
45
45
|
import { Heading, HeadingProps, HeadingVariant } from "./primitives/heading.js";
|
|
46
46
|
import { PageShell, PageShellProps } from "./primitives/page-shell.js";
|
|
47
47
|
import { Field, FieldProps, fieldMessageId } from "./primitives/field.js";
|
|
48
|
-
import {
|
|
48
|
+
import { StatusPill, StatusPillProps, StatusTone } from "./primitives/status-pill.js";
|
|
49
|
+
import { SettingsList, SettingsListAction, SettingsListColumns, SettingsListItem, SettingsListItemProps, SettingsListMenuItem, SettingsListProps, SettingsNote, SettingsNoteProps, SettingsRow, SettingsRowLayout, SettingsRowProps, SettingsSection, SettingsSectionProps } from "./primitives/settings.js";
|
|
49
50
|
import { PageHeader, PageHeaderProps } from "./primitives/page-header.js";
|
|
50
51
|
import { Alert, AlertDescription, AlertProps, AlertTitle, AlertTone } from "./primitives/alert.js";
|
|
51
52
|
import { Pagination, PaginationProps } from "./primitives/pagination.js";
|
|
52
|
-
import { StatusPill, StatusPillProps, StatusTone } from "./primitives/status-pill.js";
|
|
53
53
|
import { ComplianceBadge, ComplianceBadgeProps, ComplianceProduct, ComplianceStatus } from "./primitives/compliance-badge.js";
|
|
54
54
|
import { Tag, TagProps } from "./primitives/tag.js";
|
|
55
55
|
import { Chip, ChipProps } from "./primitives/chip.js";
|
|
@@ -62,4 +62,4 @@ import { SeriesSparkline, SeriesSparklineProps } from "./primitives/series-spark
|
|
|
62
62
|
import { ChartReferenceLine, MetricChart, MetricChartProps } from "./primitives/metric-chart.js";
|
|
63
63
|
import { FilterField, FilterFieldProps, Toolbar, ToolbarProps } from "./primitives/toolbar.js";
|
|
64
64
|
import { Logo, LogoProps, TangleKnot } from "@tangle-network/brand";
|
|
65
|
-
export { Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, type AlertProps, AlertTitle, type AlertTone, ArtifactPane, type ArtifactPaneProps, Avatar, AvatarFallback, AvatarImage, type AvatarProps, Badge, type BadgeProps, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, type ButtonProps, CATEGORY_TONES, Calendar, type CalendarDate, type CalendarProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, type CardTitleProps, type CategoryTone, type ChartReferenceLine, Checkbox, Chip, type ChipProps, CodeBlock, type CodeBlockProps, Collapsible, CollapsibleContent, CollapsibleTrigger, ComplianceBadge, type ComplianceBadgeProps, type ComplianceProduct, type ComplianceStatus, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, CopyButton, DatePicker, type DatePickerProps, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropZone, type DropZoneProps, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, type EmptyStateProps, Field, type FieldProps, FilterField, type FilterFieldProps, Heading, type HeadingProps, type HeadingVariant, HelpText, type HelpTextProps, HoverCard, HoverCardContent, HoverCardDescription, HoverCardHeader, HoverCardTitle, HoverCardTrigger, IconTile, type IconTileProps, InlineCode, type InlineCodeProps, Input, type InputProps, Label, Logo, type LogoProps, Metric, MetricChart, type MetricChartProps, type MetricProps, MetricStrip, type MetricStripProps, PageHeader, type PageHeaderProps, PageShell, type PageShellProps, Pagination, type PaginationProps, type PeriodDelta, Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverTrigger, Progress, RadioGroup, RadioGroupItem, SegmentedControl, type SegmentedControlOption, type SegmentedControlProps, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, type SeriesExtent, type SeriesPoint, type SeriesPointInput, type SeriesScale, SeriesSparkline, type SeriesSparklineProps, SettingsList, type SettingsListAction, type SettingsListColumns, SettingsListItem, type SettingsListItemProps, type SettingsListMenuItem, type SettingsListProps, SettingsRow, type SettingsRowLayout, type SettingsRowProps, SettingsSection, type SettingsSectionProps, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, SidebarDropZone, type SidebarDropZoneProps, Skeleton, SkeletonCard, SkeletonTable, Slider, StatCard, type StatCardProps, StatusPill, type StatusPillProps, type StatusTone, Switch, TONE_CLASSES, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, type TableProps, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Tag, type TagProps, TangleKnot, TerminalCursor, TerminalDisplay, TerminalInput, TerminalLine, TextShimmer, type TextShimmerProps, Textarea, type TextareaProps, ThemeToggle, TimeSelect, type TimeSelectProps, type Toast, ToastContainer, ToastProvider, type Tone, type ToneClasses, Toolbar, type ToolbarProps, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, type UploadFile, UploadProgress, type UploadProgressProps, Wizard, type WizardProps, WizardStep, type WizardStepProps, badgeVariants, buttonVariants, fieldMessageId, formatCalendarDate, initialsOf, localToday, normalizeSeries, parseCalendarDate, periodDelta, seriesAreaPath, seriesExtent, seriesLinePath, seriesMean, seriesScale, toneFor, useTheme, useToast };
|
|
65
|
+
export { Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, type AlertProps, AlertTitle, type AlertTone, ArtifactPane, type ArtifactPaneProps, Avatar, AvatarFallback, AvatarImage, type AvatarProps, Badge, type BadgeProps, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, type ButtonProps, CATEGORY_TONES, Calendar, type CalendarDate, type CalendarProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, type CardTitleProps, type CategoryTone, type ChartReferenceLine, Checkbox, Chip, type ChipProps, CodeBlock, type CodeBlockProps, Collapsible, CollapsibleContent, CollapsibleTrigger, ComplianceBadge, type ComplianceBadgeProps, type ComplianceProduct, type ComplianceStatus, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, CopyButton, DatePicker, type DatePickerProps, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropZone, type DropZoneProps, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, type EmptyStateProps, Field, type FieldProps, FilterField, type FilterFieldProps, Heading, type HeadingProps, type HeadingVariant, HelpText, type HelpTextProps, HoverCard, HoverCardContent, HoverCardDescription, HoverCardHeader, HoverCardTitle, HoverCardTrigger, IconTile, type IconTileProps, InlineCode, type InlineCodeProps, Input, type InputProps, Label, Logo, type LogoProps, Metric, MetricChart, type MetricChartProps, type MetricProps, MetricStrip, type MetricStripProps, PageHeader, type PageHeaderProps, PageShell, type PageShellProps, Pagination, type PaginationProps, type PeriodDelta, Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverTrigger, Progress, RadioGroup, RadioGroupItem, SegmentedControl, type SegmentedControlOption, type SegmentedControlProps, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, type SeriesExtent, type SeriesPoint, type SeriesPointInput, type SeriesScale, SeriesSparkline, type SeriesSparklineProps, SettingsList, type SettingsListAction, type SettingsListColumns, SettingsListItem, type SettingsListItemProps, type SettingsListMenuItem, type SettingsListProps, SettingsNote, type SettingsNoteProps, SettingsRow, type SettingsRowLayout, type SettingsRowProps, SettingsSection, type SettingsSectionProps, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, SidebarDropZone, type SidebarDropZoneProps, Skeleton, SkeletonCard, SkeletonTable, Slider, StatCard, type StatCardProps, StatusPill, type StatusPillProps, type StatusTone, Switch, TONE_CLASSES, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, type TableProps, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Tag, type TagProps, TangleKnot, TerminalCursor, TerminalDisplay, TerminalInput, TerminalLine, TextShimmer, type TextShimmerProps, Textarea, type TextareaProps, ThemeToggle, TimeSelect, type TimeSelectProps, type Toast, ToastContainer, ToastProvider, type Tone, type ToneClasses, Toolbar, type ToolbarProps, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, type UploadFile, UploadProgress, type UploadProgressProps, Wizard, type WizardProps, WizardStep, type WizardStepProps, badgeVariants, buttonVariants, fieldMessageId, formatCalendarDate, initialsOf, localToday, normalizeSeries, parseCalendarDate, periodDelta, seriesAreaPath, seriesExtent, seriesLinePath, seriesMean, seriesScale, toneFor, useTheme, useToast };
|
package/dist/primitives.js
CHANGED
|
@@ -43,11 +43,11 @@ import { InlineCode } from "./primitives/code-block.js";
|
|
|
43
43
|
import { ThemeToggle, useTheme } from "./primitives/theme-toggle.js";
|
|
44
44
|
import { PageShell } from "./primitives/page-shell.js";
|
|
45
45
|
import { Field, fieldMessageId } from "./primitives/field.js";
|
|
46
|
-
import {
|
|
46
|
+
import { StatusPill } from "./primitives/status-pill.js";
|
|
47
|
+
import { SettingsList, SettingsListItem, SettingsNote, SettingsRow, SettingsSection } from "./primitives/settings.js";
|
|
47
48
|
import { PageHeader } from "./primitives/page-header.js";
|
|
48
49
|
import { Alert, AlertDescription, AlertTitle } from "./primitives/alert.js";
|
|
49
50
|
import { Pagination } from "./primitives/pagination.js";
|
|
50
|
-
import { StatusPill } from "./primitives/status-pill.js";
|
|
51
51
|
import { ComplianceBadge } from "./primitives/compliance-badge.js";
|
|
52
52
|
import { CATEGORY_TONES, TONE_CLASSES, toneFor } from "./primitives/tone.js";
|
|
53
53
|
import { Tag } from "./primitives/tag.js";
|
|
@@ -62,4 +62,4 @@ import { SeriesSparkline } from "./primitives/series-sparkline.js";
|
|
|
62
62
|
import { MetricChart } from "./primitives/metric-chart.js";
|
|
63
63
|
import { FilterField, Toolbar } from "./primitives/toolbar.js";
|
|
64
64
|
import { Logo, TangleKnot } from "@tangle-network/brand";
|
|
65
|
-
export { Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, ArtifactPane, Avatar, AvatarFallback, AvatarImage, Badge, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, CATEGORY_TONES, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Chip, CodeBlock, Collapsible, CollapsibleContent, CollapsibleTrigger, ComplianceBadge, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, CopyButton, DatePicker, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropZone, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, Field, FilterField, Heading, HelpText, HoverCard, HoverCardContent, HoverCardDescription, HoverCardHeader, HoverCardTitle, HoverCardTrigger, IconTile, InlineCode, Input, Label, Logo, Metric, MetricChart, MetricStrip, PageHeader, PageShell, Pagination, Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverTrigger, Progress, RadioGroup, RadioGroupItem, SegmentedControl, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, SeriesSparkline, SettingsList, SettingsListItem, SettingsRow, SettingsSection, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, SidebarDropZone, Skeleton, SkeletonCard, SkeletonTable, Slider, StatCard, StatusPill, Switch, TONE_CLASSES, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Tag, TangleKnot, TerminalCursor, TerminalDisplay, TerminalInput, TerminalLine, TextShimmer, Textarea, ThemeToggle, TimeSelect, ToastContainer, ToastProvider, Toolbar, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UploadProgress, Wizard, WizardStep, badgeVariants, buttonVariants, fieldMessageId, formatCalendarDate, initialsOf, localToday, normalizeSeries, parseCalendarDate, periodDelta, seriesAreaPath, seriesExtent, seriesLinePath, seriesMean, seriesScale, toneFor, useTheme, useToast };
|
|
65
|
+
export { Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, ArtifactPane, Avatar, AvatarFallback, AvatarImage, Badge, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, CATEGORY_TONES, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Chip, CodeBlock, Collapsible, CollapsibleContent, CollapsibleTrigger, ComplianceBadge, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, CopyButton, DatePicker, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropZone, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, Field, FilterField, Heading, HelpText, HoverCard, HoverCardContent, HoverCardDescription, HoverCardHeader, HoverCardTitle, HoverCardTrigger, IconTile, InlineCode, Input, Label, Logo, Metric, MetricChart, MetricStrip, PageHeader, PageShell, Pagination, Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverTrigger, Progress, RadioGroup, RadioGroupItem, SegmentedControl, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, SeriesSparkline, SettingsList, SettingsListItem, SettingsNote, SettingsRow, SettingsSection, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, SidebarDropZone, Skeleton, SkeletonCard, SkeletonTable, Slider, StatCard, StatusPill, Switch, TONE_CLASSES, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Tag, TangleKnot, TerminalCursor, TerminalDisplay, TerminalInput, TerminalLine, TextShimmer, Textarea, ThemeToggle, TimeSelect, ToastContainer, ToastProvider, Toolbar, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UploadProgress, Wizard, WizardStep, badgeVariants, buttonVariants, fieldMessageId, formatCalendarDate, initialsOf, localToday, normalizeSeries, parseCalendarDate, periodDelta, seriesAreaPath, seriesExtent, seriesLinePath, seriesMean, seriesScale, toneFor, useTheme, useToast };
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { cn } from "../lib/utils.js";
|
|
2
1
|
import { CodeBlock } from "../markdown/code-block.js";
|
|
3
2
|
import { getToolDisplayMetadata } from "../utils/tool-display.js";
|
|
4
3
|
import { CommandPreview } from "../tool-previews/command-preview.js";
|
|
@@ -9,9 +8,10 @@ import { WebSearchPreview } from "../tool-previews/web-search-preview.js";
|
|
|
9
8
|
import { QuestionPreview } from "../tool-previews/question-preview.js";
|
|
10
9
|
import { DiffPreview } from "../tool-previews/diff-preview.js";
|
|
11
10
|
import { ExpandableContent } from "./expandable-content.js";
|
|
11
|
+
import { RunStatusIcon } from "./status-meta.js";
|
|
12
12
|
import { memo } from "react";
|
|
13
13
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
14
|
-
import {
|
|
14
|
+
import { ArrowLeft, ArrowRight, FileText } from "lucide-react";
|
|
15
15
|
// src/run/expanded-tool-detail.tsx
|
|
16
16
|
const FLUSH_TOGGLE = "mx-3 mb-2";
|
|
17
17
|
const EXT_LANG = {
|
|
@@ -144,7 +144,11 @@ const ExpandedToolDetail = memo(({ part }) => {
|
|
|
144
144
|
className: "overflow-hidden rounded-[var(--radius-lg)] border border-[var(--surface-danger-border)]",
|
|
145
145
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
146
146
|
className: "flex items-center gap-2 border-b border-[var(--surface-danger-border)] bg-[var(--surface-danger-bg)] px-3 py-2",
|
|
147
|
-
children: [/* @__PURE__ */ jsx(
|
|
147
|
+
children: [/* @__PURE__ */ jsx(RunStatusIcon, {
|
|
148
|
+
status: "failed",
|
|
149
|
+
"aria-hidden": true,
|
|
150
|
+
className: "size-3"
|
|
151
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
148
152
|
className: "text-xs font-medium uppercase tracking-[0.08em] text-[var(--surface-danger-text)]",
|
|
149
153
|
children: "Error"
|
|
150
154
|
})]
|
|
@@ -159,7 +163,11 @@ const ExpandedToolDetail = memo(({ part }) => {
|
|
|
159
163
|
}),
|
|
160
164
|
(status === "pending" || status === "running") && /* @__PURE__ */ jsxs("div", {
|
|
161
165
|
className: "flex items-center gap-2 rounded-[var(--radius-md)] border border-border bg-muted px-3 py-3 text-xs text-muted-foreground",
|
|
162
|
-
children: [/* @__PURE__ */ jsx(
|
|
166
|
+
children: [/* @__PURE__ */ jsx(RunStatusIcon, {
|
|
167
|
+
status: "running",
|
|
168
|
+
"aria-hidden": true,
|
|
169
|
+
className: "size-3"
|
|
170
|
+
}), "Running…"]
|
|
163
171
|
})
|
|
164
172
|
]
|
|
165
173
|
});
|
package/dist/run/run-group.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { cn } from "../lib/utils.js";
|
|
2
2
|
import { formatDuration } from "../utils/format.js";
|
|
3
|
+
import { RunStatusIcon, statusMeta } from "./status-meta.js";
|
|
3
4
|
import { InlineToolItem } from "./inline-tool-item.js";
|
|
4
5
|
import { Markdown } from "../markdown/markdown.js";
|
|
5
6
|
import { InlineThinkingItem } from "./inline-thinking-item.js";
|
|
@@ -8,7 +9,7 @@ import { OpenUIArtifactRenderer } from "../openui/openui-artifact-renderer.js";
|
|
|
8
9
|
import { TRANSCRIPT_TEXT } from "../chat/transcript-text.js";
|
|
9
10
|
import { memo, useMemo } from "react";
|
|
10
11
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
-
import { Bot, ChevronDown, ChevronRight, ClipboardList, FileEdit, FileSearch, Globe,
|
|
12
|
+
import { Bot, ChevronDown, ChevronRight, ClipboardList, FileEdit, FileSearch, Globe, PencilLine, Search, Settings, Terminal } from "lucide-react";
|
|
12
13
|
import * as Collapsible from "@radix-ui/react-collapsible";
|
|
13
14
|
// src/run/run-group.tsx
|
|
14
15
|
/**
|
|
@@ -46,7 +47,11 @@ function AssistantShell({ branding, isStreaming, children }) {
|
|
|
46
47
|
className: "flex items-center gap-2 px-1 font-medium text-muted-foreground text-xs",
|
|
47
48
|
children: [/* @__PURE__ */ jsx("span", { children: branding.label }), isStreaming ? /* @__PURE__ */ jsxs("span", {
|
|
48
49
|
className: "inline-flex items-center gap-1.5",
|
|
49
|
-
children: [/* @__PURE__ */ jsx(
|
|
50
|
+
children: [/* @__PURE__ */ jsx(RunStatusIcon, {
|
|
51
|
+
status: "running",
|
|
52
|
+
"aria-hidden": true,
|
|
53
|
+
className: "size-3"
|
|
54
|
+
}), "Thinking"]
|
|
50
55
|
}) : null]
|
|
51
56
|
}), /* @__PURE__ */ jsx("div", {
|
|
52
57
|
className: ASSISTANT_SHELL,
|
|
@@ -249,7 +254,10 @@ const RunGroup = memo(({ run, partMap, collapsed, onToggle, branding = DEFAULT_B
|
|
|
249
254
|
}, key);
|
|
250
255
|
if (toolPart.state.status === "running") return /* @__PURE__ */ jsxs("div", {
|
|
251
256
|
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",
|
|
252
|
-
children: [/* @__PURE__ */ jsx(
|
|
257
|
+
children: [/* @__PURE__ */ jsx(RunStatusIcon, {
|
|
258
|
+
status: "running",
|
|
259
|
+
"aria-hidden": true
|
|
260
|
+
}), "Building view…"]
|
|
253
261
|
}, key);
|
|
254
262
|
}
|
|
255
263
|
if (part.type === "text" && !part.synthetic && part.text.trim()) return /* @__PURE__ */ jsx("div", {
|
|
@@ -302,12 +310,13 @@ const RunGroup = memo(({ run, partMap, collapsed, onToggle, branding = DEFAULT_B
|
|
|
302
310
|
}) : null,
|
|
303
311
|
/* @__PURE__ */ jsxs("span", {
|
|
304
312
|
className: "ml-auto flex shrink-0 items-center gap-1.5",
|
|
305
|
-
children: [/* @__PURE__ */ jsx(CategoryBadges, { categories: stats.toolCategories }),
|
|
306
|
-
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)]",
|
|
307
|
-
children: [/* @__PURE__ */ jsx(Loader2, { className: "h-2.5 w-2.5 animate-spin" }), "Running"]
|
|
308
|
-
}) : /* @__PURE__ */ jsxs("span", {
|
|
313
|
+
children: [/* @__PURE__ */ jsx(CategoryBadges, { categories: stats.toolCategories }), /* @__PURE__ */ jsxs("span", {
|
|
309
314
|
className: "inline-flex items-center gap-1 rounded-full border border-border px-2 py-px text-[10px] font-semibold uppercase text-muted-foreground",
|
|
310
|
-
children: [/* @__PURE__ */ jsx(
|
|
315
|
+
children: [/* @__PURE__ */ jsx(RunStatusIcon, {
|
|
316
|
+
status: isStreaming ? "running" : "done",
|
|
317
|
+
"aria-hidden": true,
|
|
318
|
+
className: "size-3"
|
|
319
|
+
}), statusMeta(isStreaming ? "running" : "done").label]
|
|
311
320
|
})]
|
|
312
321
|
})
|
|
313
322
|
]
|
|
@@ -346,7 +355,10 @@ const RunGroup = memo(({ run, partMap, collapsed, onToggle, branding = DEFAULT_B
|
|
|
346
355
|
});
|
|
347
356
|
else if (toolPart.state.status === "running") node = /* @__PURE__ */ jsxs("div", {
|
|
348
357
|
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",
|
|
349
|
-
children: [/* @__PURE__ */ jsx(
|
|
358
|
+
children: [/* @__PURE__ */ jsx(RunStatusIcon, {
|
|
359
|
+
status: "running",
|
|
360
|
+
"aria-hidden": true
|
|
361
|
+
}), "Building view…"]
|
|
350
362
|
});
|
|
351
363
|
}
|
|
352
364
|
if (node === null) node = /* @__PURE__ */ jsx(InlineToolItem, {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { focusRing } from "../lib/focus.js";
|
|
2
2
|
import { cn } from "../lib/utils.js";
|
|
3
|
+
import { RunStatusIcon } from "./status-meta.js";
|
|
3
4
|
import { useState } from "react";
|
|
4
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
-
import { ChevronRight
|
|
6
|
+
import { ChevronRight } from "lucide-react";
|
|
6
7
|
// src/run/run-phase-list.tsx
|
|
7
8
|
function PhaseRow({ phase }) {
|
|
8
9
|
const [open, setOpen] = useState(false);
|
|
@@ -28,13 +29,9 @@ function PhaseRow({ phase }) {
|
|
|
28
29
|
children: [" · ", phase.summary]
|
|
29
30
|
})]
|
|
30
31
|
}),
|
|
31
|
-
phase.status
|
|
32
|
-
|
|
33
|
-
className: "mt-1
|
|
34
|
-
}),
|
|
35
|
-
phase.status === "error" && /* @__PURE__ */ jsx(CircleAlert, {
|
|
36
|
-
"aria-label": "Had an error",
|
|
37
|
-
className: "mt-1 size-4 shrink-0 text-[var(--surface-danger-text)]"
|
|
32
|
+
phase.status && phase.status !== "done" && /* @__PURE__ */ jsx(RunStatusIcon, {
|
|
33
|
+
status: phase.status,
|
|
34
|
+
className: "mt-1"
|
|
38
35
|
})
|
|
39
36
|
]
|
|
40
37
|
}), open && /* @__PURE__ */ jsx("div", {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { LucideIcon, LucideProps } from "lucide-react";
|
|
2
|
+
/** The states an agent or a run reports. Every surface names them with `statusMeta`. */
|
|
3
|
+
export type RunStatus = "running" | "waiting" | "needs-you" | "done" | "failed" | "stopped" | "idle" | "unknown";
|
|
4
|
+
export interface StatusMeta {
|
|
5
|
+
/** The one word for the state. A qualifier such as "Shipped" follows Done; it never replaces it. */
|
|
6
|
+
label: string;
|
|
7
|
+
/** The lucide glyph, drawn on the 16px grid at stroke 1.75 (`RunStatusIcon` does both). */
|
|
8
|
+
icon: LucideIcon;
|
|
9
|
+
/** The Brand colour token for the glyph and any bare status text: `color: var(<token>)`. */
|
|
10
|
+
token: `--${string}`;
|
|
11
|
+
}
|
|
12
|
+
/** Any status string as a `RunStatus`; a value nothing names reads as Unknown, never as a guess. */
|
|
13
|
+
export declare function runStatus(status: string): RunStatus;
|
|
14
|
+
/** The label, glyph and colour token for a status, in every surface. */
|
|
15
|
+
export declare function statusMeta(status: RunStatus | (string & {})): StatusMeta;
|
|
16
|
+
export interface RunStatusIconProps extends Omit<LucideProps, "ref"> {
|
|
17
|
+
status: RunStatus | (string & {});
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A status glyph on the icon grid, in its token colour and labelled with its
|
|
21
|
+
* word. Pass `aria-hidden` where the label is already printed beside it.
|
|
22
|
+
* Running breathes on `--motion-ambient`, the page's one loop period; the
|
|
23
|
+
* breathe is opacity only, so it is the essential motion reduced motion keeps.
|
|
24
|
+
*/
|
|
25
|
+
export declare function RunStatusIcon({ status, className, style, ...props }: RunStatusIconProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { cn } from "../lib/utils.js";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { CircleCheck, CircleDashed, CircleDot, CircleQuestionMark, CircleStop, CircleX, Hand, Hourglass } from "lucide-react";
|
|
4
|
+
// src/run/status-meta.tsx
|
|
5
|
+
const META = {
|
|
6
|
+
running: {
|
|
7
|
+
label: "Running",
|
|
8
|
+
icon: CircleDot,
|
|
9
|
+
token: "--surface-info-text"
|
|
10
|
+
},
|
|
11
|
+
waiting: {
|
|
12
|
+
label: "Waiting",
|
|
13
|
+
icon: Hourglass,
|
|
14
|
+
token: "--surface-neutral-text"
|
|
15
|
+
},
|
|
16
|
+
"needs-you": {
|
|
17
|
+
label: "Needs you",
|
|
18
|
+
icon: Hand,
|
|
19
|
+
token: "--surface-warning-text"
|
|
20
|
+
},
|
|
21
|
+
done: {
|
|
22
|
+
label: "Done",
|
|
23
|
+
icon: CircleCheck,
|
|
24
|
+
token: "--surface-success-text"
|
|
25
|
+
},
|
|
26
|
+
failed: {
|
|
27
|
+
label: "Failed",
|
|
28
|
+
icon: CircleX,
|
|
29
|
+
token: "--surface-danger-text"
|
|
30
|
+
},
|
|
31
|
+
stopped: {
|
|
32
|
+
label: "Stopped",
|
|
33
|
+
icon: CircleStop,
|
|
34
|
+
token: "--surface-neutral-text"
|
|
35
|
+
},
|
|
36
|
+
idle: {
|
|
37
|
+
label: "Idle",
|
|
38
|
+
icon: CircleDashed,
|
|
39
|
+
token: "--surface-neutral-text"
|
|
40
|
+
},
|
|
41
|
+
unknown: {
|
|
42
|
+
label: "Unknown",
|
|
43
|
+
icon: CircleQuestionMark,
|
|
44
|
+
token: "--surface-neutral-text"
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
const ALIASES = {
|
|
48
|
+
active: "running",
|
|
49
|
+
in_progress: "running",
|
|
50
|
+
"in-progress": "running",
|
|
51
|
+
streaming: "running",
|
|
52
|
+
pending: "waiting",
|
|
53
|
+
queued: "waiting",
|
|
54
|
+
blocked: "waiting",
|
|
55
|
+
"attention-needed": "needs-you",
|
|
56
|
+
needs_you: "needs-you",
|
|
57
|
+
needs_input: "needs-you",
|
|
58
|
+
awaiting_input: "needs-you",
|
|
59
|
+
completed: "done",
|
|
60
|
+
complete: "done",
|
|
61
|
+
success: "done",
|
|
62
|
+
succeeded: "done",
|
|
63
|
+
shipped: "done",
|
|
64
|
+
error: "failed",
|
|
65
|
+
errored: "failed",
|
|
66
|
+
cancelled: "stopped",
|
|
67
|
+
canceled: "stopped",
|
|
68
|
+
aborted: "stopped"
|
|
69
|
+
};
|
|
70
|
+
/** Any status string as a `RunStatus`; a value nothing names reads as Unknown, never as a guess. */
|
|
71
|
+
function runStatus(status) {
|
|
72
|
+
const key = status.trim().toLowerCase();
|
|
73
|
+
if (Object.hasOwn(META, key)) return key;
|
|
74
|
+
return Object.hasOwn(ALIASES, key) ? ALIASES[key] : "unknown";
|
|
75
|
+
}
|
|
76
|
+
/** The label, glyph and colour token for a status, in every surface. */
|
|
77
|
+
function statusMeta(status) {
|
|
78
|
+
return META[runStatus(status)];
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* A status glyph on the icon grid, in its token colour and labelled with its
|
|
82
|
+
* word. Pass `aria-hidden` where the label is already printed beside it.
|
|
83
|
+
* Running breathes on `--motion-ambient`, the page's one loop period; the
|
|
84
|
+
* breathe is opacity only, so it is the essential motion reduced motion keeps.
|
|
85
|
+
*/
|
|
86
|
+
function RunStatusIcon({ status, className, style, ...props }) {
|
|
87
|
+
const key = runStatus(status);
|
|
88
|
+
const { label, icon: Icon, token } = META[key];
|
|
89
|
+
const running = key === "running";
|
|
90
|
+
return /* @__PURE__ */ jsx(Icon, {
|
|
91
|
+
role: "img",
|
|
92
|
+
"aria-label": label,
|
|
93
|
+
size: 16,
|
|
94
|
+
strokeWidth: 1.75,
|
|
95
|
+
"data-run-status": key,
|
|
96
|
+
"data-motion": running ? "essential" : void 0,
|
|
97
|
+
className: cn("shrink-0", running && "animate-[tangle-breathe_var(--motion-ambient)_infinite]", className),
|
|
98
|
+
style: {
|
|
99
|
+
color: `var(${token})`,
|
|
100
|
+
...style
|
|
101
|
+
},
|
|
102
|
+
...props
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
export { RunStatusIcon, runStatus, statusMeta };
|
package/dist/run.d.ts
CHANGED
|
@@ -9,4 +9,5 @@ import { LiveDuration } from "./run/run-item-primitives.js";
|
|
|
9
9
|
import { TaskList, TaskListItem, TaskListProps, TaskStatus, showsTaskPriority, taskProgress, taskStatus } from "./run/task-list.js";
|
|
10
10
|
import { ApprovalCard, ApprovalCardProps, ApprovalDiffFile, ApprovalDiffSummary, ApprovalPlanStep } from "./run/approval-card.js";
|
|
11
11
|
import { RunPhase, RunPhaseList } from "./run/run-phase-list.js";
|
|
12
|
-
|
|
12
|
+
import { RunStatus, RunStatusIcon, RunStatusIconProps, StatusMeta, runStatus, statusMeta } from "./run/status-meta.js";
|
|
13
|
+
export { ApprovalCard, type ApprovalCardProps, type ApprovalDiffFile, ApprovalDiffSummary, type ApprovalPlanStep, ExpandedToolDetail, type ExpandedToolDetailProps, type FeedSegment, InlineThinkingItem, type InlineThinkingItemProps, InlineToolItem, type InlineToolItemProps, LiveDuration, RunGroup, type RunGroupProps, type RunPhase, RunPhaseList, RunRowShell, type RunRowShellProps, type RunRowStatus, RunRowStatusDot, type RunStatus, RunStatusIcon, type RunStatusIconProps, type StatusMeta, TaskList, type TaskListItem, type TaskListProps, type TaskStatus, type ToolCallData, ToolCallFeed, type ToolCallFeedProps, type ToolCallStatus, type ToolCallType, parseToolEvent, runStatus, showsTaskPriority, statusMeta, taskProgress, taskStatus };
|
package/dist/run.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { RunStatusIcon, runStatus, statusMeta } from "./run/status-meta.js";
|
|
1
2
|
import { ExpandedToolDetail } from "./run/expanded-tool-detail.js";
|
|
2
3
|
import { RunRowShell, RunRowStatusDot } from "./run/run-row-shell.js";
|
|
3
4
|
import { InlineToolItem } from "./run/inline-tool-item.js";
|
|
@@ -8,4 +9,4 @@ import { ToolCallFeed, parseToolEvent } from "./run/tool-call-feed.js";
|
|
|
8
9
|
import { TaskList, showsTaskPriority, taskProgress, taskStatus } from "./run/task-list.js";
|
|
9
10
|
import { ApprovalCard, ApprovalDiffSummary } from "./run/approval-card.js";
|
|
10
11
|
import { RunPhaseList } from "./run/run-phase-list.js";
|
|
11
|
-
export { ApprovalCard, ApprovalDiffSummary, ExpandedToolDetail, InlineThinkingItem, InlineToolItem, LiveDuration, RunGroup, RunPhaseList, RunRowShell, RunRowStatusDot, TaskList, ToolCallFeed, parseToolEvent, showsTaskPriority, taskProgress, taskStatus };
|
|
12
|
+
export { ApprovalCard, ApprovalDiffSummary, ExpandedToolDetail, InlineThinkingItem, InlineToolItem, LiveDuration, RunGroup, RunPhaseList, RunRowShell, RunRowStatusDot, RunStatusIcon, TaskList, ToolCallFeed, parseToolEvent, runStatus, showsTaskPriority, statusMeta, taskProgress, taskStatus };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/ui",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.50.1",
|
|
4
4
|
"description": "Generic React UI components for Tangle products — primitives, chat, run, files, editor, markdown.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -166,7 +166,7 @@
|
|
|
166
166
|
"peerDependencies": {
|
|
167
167
|
"@hocuspocus/provider": ">=2.15.0 <5.0.0",
|
|
168
168
|
"@nanostores/react": ">=0.8.4 <3.0.0",
|
|
169
|
-
"@tangle-network/brand": "^1.
|
|
169
|
+
"@tangle-network/brand": "^1.31.0",
|
|
170
170
|
"@tiptap/core": ">=3.20.4 <4.0.0",
|
|
171
171
|
"@tiptap/extension-collaboration": ">=3.20.4 <4.0.0",
|
|
172
172
|
"@tiptap/extension-collaboration-caret": ">=3.7.0 <4.0.0",
|
|
@@ -307,3 +307,12 @@ describe("transcript type scale", () => {
|
|
|
307
307
|
expect(textClasses(agent)).toEqual(textClasses(user))
|
|
308
308
|
})
|
|
309
309
|
})
|
|
310
|
+
|
|
311
|
+
describe("AgentTimeline status cards", () => {
|
|
312
|
+
it("marks a failed card with the failed glyph and keeps the triangle for warnings", () => {
|
|
313
|
+
const glyph = (tone: "error" | "warning") =>
|
|
314
|
+
render(<AgentTimeline items={[{ id: tone, kind: "status", label: tone, tone }]} />).container.querySelector("svg")?.getAttribute("class")
|
|
315
|
+
expect(glyph("error")).toContain("lucide-circle-x")
|
|
316
|
+
expect(glyph("warning")).toContain("lucide-triangle-alert")
|
|
317
|
+
})
|
|
318
|
+
})
|