@sentry/junior-dashboard 0.247.0 → 0.249.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.
- package/dist/app.js +69 -15
- package/dist/client.js +51 -50
- package/dist/index.js +69 -15
- package/dist/tailwind.css +1 -1
- package/package.json +3 -3
- package/src/client/App.tsx +1 -5
- package/src/client/components/ActorAvatar.tsx +7 -4
- package/src/client/components/AutomationCard.tsx +2 -2
- package/src/client/components/Button.tsx +12 -11
- package/src/client/components/ConversationList.tsx +3 -3
- package/src/client/components/ConversationSummary.tsx +2 -1
- package/src/client/components/DetailList.tsx +3 -3
- package/src/client/components/Drawer.tsx +2 -2
- package/src/client/components/EmptyTelemetry.tsx +1 -1
- package/src/client/components/Field.tsx +1 -2
- package/src/client/components/FilterBar.tsx +6 -6
- package/src/client/components/Metric.tsx +11 -16
- package/src/client/components/Notice.tsx +7 -7
- package/src/client/components/PageContentSkeleton.tsx +2 -2
- package/src/client/components/Pagination.tsx +2 -2
- package/src/client/components/ParticipantAvatarStack.tsx +4 -4
- package/src/client/components/ProfileMenu.tsx +5 -7
- package/src/client/components/README.md +122 -58
- package/src/client/components/SearchInput.tsx +4 -3
- package/src/client/components/SegmentedNav.tsx +10 -17
- package/src/client/components/SegmentedTabs.tsx +3 -3
- package/src/client/components/Select.tsx +1 -1
- package/src/client/components/SelectableRow.tsx +2 -2
- package/src/client/components/Skeleton.tsx +1 -1
- package/src/client/components/StatusChip.tsx +1 -1
- package/src/client/components/StatusDot.tsx +1 -1
- package/src/client/components/TextInput.tsx +1 -1
- package/src/client/components/Tooltip.tsx +2 -2
- package/src/client/components/VersionDriftBanner.tsx +2 -2
- package/src/client/components/charts/ActivityChart.tsx +5 -6
- package/src/client/components/charts/CacheWrites.tsx +3 -3
- package/src/client/components/charts/ChartHeader.tsx +4 -4
- package/src/client/components/charts/ChartLegend.tsx +1 -1
- package/src/client/components/charts/InputCacheChart.tsx +5 -5
- package/src/client/components/charts/WorkspaceUsageChart.tsx +4 -11
- package/src/client/components/controls/DirectorySortSelect.tsx +2 -2
- package/src/client/components/directory/DirectoryMetric.tsx +2 -2
- package/src/client/components/directory/DirectoryRowsSkeleton.tsx +5 -5
- package/src/client/components/directory/DirectoryTable.tsx +3 -3
- package/src/client/components/layout/CardHeader.tsx +4 -4
- package/src/client/components/layout/DashboardChrome.tsx +9 -3
- package/src/client/components/layout/DashboardHeader.tsx +7 -7
- package/src/client/components/layout/PageHeader.tsx +2 -2
- package/src/client/components/layout/SecondaryNavigation.tsx +7 -14
- package/src/client/components/layout/SectionIntro.tsx +1 -1
- package/src/client/components/layout/SectionTitle.tsx +1 -1
- package/src/client/components/metrics/StatCard.tsx +2 -2
- package/src/client/conversations/ConversationArchiveNotices.tsx +1 -1
- package/src/client/conversations/ConversationBrief.tsx +4 -4
- package/src/client/conversations/ConversationChildAgents.tsx +13 -4
- package/src/client/conversations/ConversationComposer.tsx +8 -7
- package/src/client/conversations/ConversationHeader.tsx +5 -5
- package/src/client/conversations/ConversationHeaderActions.tsx +9 -9
- package/src/client/conversations/ConversationHomeList.tsx +3 -3
- package/src/client/conversations/ConversationListStatusIcon.tsx +1 -1
- package/src/client/conversations/ConversationMemories.tsx +4 -4
- package/src/client/conversations/ConversationMeta.tsx +30 -11
- package/src/client/conversations/ConversationPage.tsx +13 -5
- package/src/client/conversations/ConversationSidebar.tsx +6 -6
- package/src/client/conversations/ConversationUsageBreakdown.tsx +278 -0
- package/src/client/conversations/ConversationWorkspace.tsx +1 -1
- package/src/client/conversations/ConversationWorkspaceLoading.tsx +4 -4
- package/src/client/conversations/CopyMarkdownButton.tsx +1 -1
- package/src/client/conversations/EventUsage.tsx +2 -2
- package/src/client/conversations/PendingMailboxStack.tsx +5 -5
- package/src/client/conversations/README.md +9 -0
- package/src/client/conversations/SubagentTranscriptDrawer.tsx +39 -23
- package/src/client/conversations/TelemetryMetrics.tsx +327 -180
- package/src/client/conversations/ToolFrame.tsx +36 -14
- package/src/client/conversations/TranscriptActivityGroup.tsx +10 -3
- package/src/client/conversations/TranscriptAttachmentsDeliveredView.tsx +4 -6
- package/src/client/conversations/TranscriptContextEventView.tsx +2 -2
- package/src/client/conversations/TranscriptEventView.tsx +1 -1
- package/src/client/conversations/TranscriptMarkdown.tsx +3 -3
- package/src/client/conversations/TranscriptMessageContextView.tsx +7 -7
- package/src/client/conversations/TranscriptMessageView.tsx +2 -6
- package/src/client/conversations/TranscriptRailEvent.tsx +20 -8
- package/src/client/conversations/TranscriptReasoningView.tsx +12 -12
- package/src/client/conversations/TranscriptStructuredEventView.tsx +16 -11
- package/src/client/conversations/TranscriptSubagentView.tsx +64 -39
- package/src/client/conversations/TranscriptText.tsx +5 -4
- package/src/client/conversations/TranscriptToolView.tsx +9 -11
- package/src/client/conversations/TranscriptTurnContextView.tsx +3 -3
- package/src/client/conversations/TranscriptView.tsx +3 -3
- package/src/client/conversations/UsageCard.tsx +172 -0
- package/src/client/conversations/eventTranscript.ts +7 -0
- package/src/client/conversations/transcriptMarkdownLinks.ts +2 -4
- package/src/client/conversations/transcriptStyles.ts +1 -1
- package/src/client/format.ts +1 -0
- package/src/client/pages/PersonalTokensPage.tsx +4 -4
- package/src/client/pages/admin/AdminPage.tsx +2 -2
- package/src/client/pages/automations/AutomationCostChart.tsx +2 -2
- package/src/client/pages/automations/AutomationDetailsDrawer.tsx +5 -10
- package/src/client/pages/automations/AutomationEditor.tsx +1 -1
- package/src/client/pages/automations/AutomationExecutionChart.tsx +2 -2
- package/src/client/pages/automations/AutomationExecutionStatusChart.tsx +2 -2
- package/src/client/pages/automations/AutomationExecutionsPage.tsx +4 -4
- package/src/client/pages/automations/AutomationRow.tsx +4 -4
- package/src/client/pages/automations/AutomationRunsPage.tsx +3 -3
- package/src/client/pages/automations/AutomationScheduleFields.tsx +1 -1
- package/src/client/pages/automations/AutomationVersionsPage.tsx +1 -1
- package/src/client/pages/code/CodeActivityChart.tsx +7 -6
- package/src/client/pages/code/CodeChangeRow.tsx +1 -1
- package/src/client/pages/code/CodePage.tsx +5 -5
- package/src/client/pages/code/RepositoryPage.tsx +2 -2
- package/src/client/pages/dev/ComponentsPage.tsx +40 -146
- package/src/client/pages/dev/TranscriptActivityFixtures.tsx +206 -0
- package/src/client/pages/locations/LocationDetailPage.tsx +4 -4
- package/src/client/pages/locations/LocationDirectory.tsx +1 -1
- package/src/client/pages/locations/PrivateActivityCard.tsx +3 -3
- package/src/client/pages/memory/MemoryCostChart.tsx +3 -5
- package/src/client/pages/memory/MemoryDetailsDrawer.tsx +5 -5
- package/src/client/pages/memory/MemoryPage.tsx +15 -15
- package/src/client/pages/memory/MemoryTimeline.tsx +3 -5
- package/src/client/pages/people/ContributionGrid.tsx +8 -5
- package/src/client/pages/people/PersonProfilePage.tsx +3 -6
- package/src/client/pages/people/ProfilePluginReports.tsx +2 -2
- package/src/client/pages/system/GuardianActivity.tsx +9 -9
- package/src/client/pages/system/PluginBarChart.tsx +4 -6
- package/src/client/pages/system/PluginDetails.tsx +11 -7
- package/src/client/pages/system/PluginPanels.tsx +8 -8
- package/src/client/pages/system/PluginReportRecordSet.tsx +14 -14
- package/src/client/pages/system/PluginReports.tsx +7 -11
- package/src/client/pages/system/SkillInventory.tsx +9 -9
- package/src/client/pages/system/SystemActivity.tsx +1 -1
- package/src/client/pages/system/SystemPage.tsx +3 -6
- package/src/client/pages/system/WorkspaceDetails.tsx +2 -5
- package/src/client/pages/system/WorkspaceEditor.tsx +2 -2
- package/src/client/pages/system/WorkspaceList.tsx +2 -2
- package/src/client/pages/user/PluginUserPage.tsx +3 -3
- package/src/client/styles.ts +5 -4
- package/src/client/types.ts +3 -0
- package/src/mock-reporting/fixtures.ts +73 -14
- package/src/tailwind.css +36 -38
|
@@ -26,11 +26,12 @@ export const TranscriptText = memo(function TranscriptText(props: {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
return (
|
|
29
|
-
<
|
|
30
|
-
|
|
29
|
+
<div
|
|
30
|
+
className="min-w-0 overflow-hidden rounded-md border border-dashboard-border-subtle bg-dashboard-surface-panel px-3 py-2.5"
|
|
31
31
|
key={index}
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
>
|
|
33
|
+
<HighlightedCode code={block.code} language={block.language} />
|
|
34
|
+
</div>
|
|
34
35
|
);
|
|
35
36
|
})}
|
|
36
37
|
</div>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { memo, useMemo } from "react";
|
|
2
|
-
import { TriangleAlert } from "lucide-react";
|
|
2
|
+
import { TriangleAlert, Wrench } from "lucide-react";
|
|
3
3
|
|
|
4
4
|
import { HighlightedCode } from "../code";
|
|
5
5
|
import {
|
|
@@ -45,6 +45,12 @@ export const TranscriptToolView = memo(function TranscriptToolView(props: {
|
|
|
45
45
|
const frame = (
|
|
46
46
|
<ToolFrame
|
|
47
47
|
expandable={hasDetails}
|
|
48
|
+
icon={props.part.status === "error" ? TriangleAlert : Wrench}
|
|
49
|
+
iconClassName={
|
|
50
|
+
props.part.status === "error"
|
|
51
|
+
? "text-rose-300"
|
|
52
|
+
: "text-dashboard-text-faint"
|
|
53
|
+
}
|
|
48
54
|
meta={meta}
|
|
49
55
|
mobileSummaryMeta={mobileSummary}
|
|
50
56
|
signature={signature}
|
|
@@ -78,14 +84,6 @@ function ToolSignature(props: {
|
|
|
78
84
|
|
|
79
85
|
return (
|
|
80
86
|
<>
|
|
81
|
-
{failed ? (
|
|
82
|
-
<TriangleAlert
|
|
83
|
-
aria-hidden="true"
|
|
84
|
-
className="shrink-0 !text-rose-300"
|
|
85
|
-
size={12}
|
|
86
|
-
strokeWidth={2.2}
|
|
87
|
-
/>
|
|
88
|
-
) : null}
|
|
89
87
|
<ShimmerText
|
|
90
88
|
active={shimmering}
|
|
91
89
|
aria-label={statusLabel}
|
|
@@ -109,8 +107,8 @@ function ToolSignature(props: {
|
|
|
109
107
|
function ToolPayload(props: { label: string; value: unknown }) {
|
|
110
108
|
const code = useMemo(() => stringifyPartValue(props.value), [props.value]);
|
|
111
109
|
return (
|
|
112
|
-
<div className="min-w-0 max-w-full overflow-hidden
|
|
113
|
-
<div className="pb-1.5 font-
|
|
110
|
+
<div className="min-w-0 max-w-full overflow-hidden border-dashboard-border-subtle px-3 py-2.5 [&+&]:border-t">
|
|
111
|
+
<div className="pb-1.5 font-sans text-xs font-medium leading-none text-dashboard-text-muted">
|
|
114
112
|
{props.label}
|
|
115
113
|
</div>
|
|
116
114
|
<HighlightedCode code={code} language="json" />
|
|
@@ -24,7 +24,7 @@ export function TranscriptTurnContextView(props: {
|
|
|
24
24
|
aria-expanded={open}
|
|
25
25
|
aria-label="View turn context"
|
|
26
26
|
className={cn(
|
|
27
|
-
"inline-flex size-6 shrink-0 cursor-pointer items-center justify-center rounded text-dashboard-text-muted transition-colors hover:bg-dashboard-fill-hover hover:text-dashboard-text focus-visible:bg-dashboard-fill-hover focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-dashboard-focus",
|
|
27
|
+
"inline-flex size-6 shrink-0 cursor-pointer items-center justify-center rounded-md text-dashboard-text-muted transition-colors hover:bg-dashboard-fill-hover hover:text-dashboard-text focus-visible:bg-dashboard-fill-hover focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-dashboard-focus",
|
|
28
28
|
open && "bg-dashboard-fill-hover text-dashboard-text",
|
|
29
29
|
)}
|
|
30
30
|
onClick={() => setOpen(true)}
|
|
@@ -80,13 +80,13 @@ function TurnContext(props: { context: TranscriptViewTurnContext }) {
|
|
|
80
80
|
{memory ? (
|
|
81
81
|
<Brain
|
|
82
82
|
aria-hidden="true"
|
|
83
|
-
className="shrink-0 text-
|
|
83
|
+
className="shrink-0 text-dashboard-accent-text/60"
|
|
84
84
|
size={15}
|
|
85
85
|
/>
|
|
86
86
|
) : (
|
|
87
87
|
<Braces
|
|
88
88
|
aria-hidden="true"
|
|
89
|
-
className="shrink-0 text-
|
|
89
|
+
className="shrink-0 text-dashboard-accent-text/60"
|
|
90
90
|
size={15}
|
|
91
91
|
/>
|
|
92
92
|
)}
|
|
@@ -72,10 +72,10 @@ export function Transcript(props: {
|
|
|
72
72
|
) : null}
|
|
73
73
|
{props.hasPreviousPage || props.loadingPreviousPage ? (
|
|
74
74
|
<div className="mb-3 flex items-center gap-3">
|
|
75
|
-
<span className="h-px min-w-4 flex-1 bg-
|
|
75
|
+
<span className="h-px min-w-4 flex-1 bg-dashboard-fill-strong" />
|
|
76
76
|
<button
|
|
77
77
|
aria-label="Load earlier events"
|
|
78
|
-
className="shrink-0 cursor-pointer border-0 bg-transparent px-1 py-0.5 font-sans text-xs font-medium text-dashboard-text-muted transition-colors hover:text-dashboard-text focus-visible:outline focus-visible:outline-1 focus-visible:outline-
|
|
78
|
+
className="shrink-0 cursor-pointer border-0 bg-transparent px-1 py-0.5 font-sans text-xs font-medium text-dashboard-text-muted transition-colors hover:text-dashboard-text focus-visible:outline focus-visible:outline-1 focus-visible:outline-dashboard-focus/55 disabled:cursor-not-allowed disabled:opacity-50"
|
|
79
79
|
disabled={props.loadingPreviousPage}
|
|
80
80
|
onClick={() => {
|
|
81
81
|
bottomPinning.preserveViewportForPrepend();
|
|
@@ -88,7 +88,7 @@ export function Transcript(props: {
|
|
|
88
88
|
? `Loading earlier ${historyLabel}…`
|
|
89
89
|
: `Show earlier ${historyLabel}`}
|
|
90
90
|
</button>
|
|
91
|
-
<span className="h-px min-w-4 flex-1 bg-
|
|
91
|
+
<span className="h-px min-w-4 flex-1 bg-dashboard-fill-strong" />
|
|
92
92
|
</div>
|
|
93
93
|
) : null}
|
|
94
94
|
{props.historyError ? (
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { cn } from "../styles";
|
|
2
|
+
import { ShimmerText } from "../components/ShimmerText";
|
|
3
|
+
|
|
4
|
+
export type UsageCardRow = {
|
|
5
|
+
label: string;
|
|
6
|
+
live?: boolean;
|
|
7
|
+
/** Render the label in the code face, such as a model id. */
|
|
8
|
+
code?: boolean;
|
|
9
|
+
value: string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export type UsageCardSection = {
|
|
13
|
+
/** Rows rolled up into one "N more" line, with their combined value. */
|
|
14
|
+
more?: { count: number; value: string };
|
|
15
|
+
rows: UsageCardRow[];
|
|
16
|
+
title: string;
|
|
17
|
+
/** Section total shown after the title, such as all auxiliary cost. */
|
|
18
|
+
total?: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export type UsageCardSplit = {
|
|
22
|
+
count: number;
|
|
23
|
+
self: string;
|
|
24
|
+
/** Share of the total that belongs to this agent, from 0 to 1. */
|
|
25
|
+
selfShare: number;
|
|
26
|
+
subagents: string;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export type UsageCardProps = {
|
|
30
|
+
/** Closing hint, such as where to find the full breakdown. */
|
|
31
|
+
footer?: string;
|
|
32
|
+
/** Muted detail after the title, such as a compaction count. */
|
|
33
|
+
note?: string;
|
|
34
|
+
sections: UsageCardSection[];
|
|
35
|
+
split?: UsageCardSplit;
|
|
36
|
+
title: string;
|
|
37
|
+
total: string;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const SELF_FILL = "bg-dashboard-focus/80";
|
|
41
|
+
const SUBAGENT_FILL = "bg-dashboard-focus/30";
|
|
42
|
+
|
|
43
|
+
function Swatch(props: { className: string }) {
|
|
44
|
+
return (
|
|
45
|
+
<span
|
|
46
|
+
aria-hidden="true"
|
|
47
|
+
className={cn("size-2 shrink-0 rounded-xs", props.className)}
|
|
48
|
+
/>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Summarize one usage total: the total up top, how it splits between this
|
|
54
|
+
* agent and its subagents, then the largest contributors. Long lists roll
|
|
55
|
+
* their tail into one "N more" row so the card never needs to scroll.
|
|
56
|
+
*/
|
|
57
|
+
export function UsageCard(props: UsageCardProps) {
|
|
58
|
+
const selfPercent = Math.min(
|
|
59
|
+
100,
|
|
60
|
+
Math.max(0, (props.split?.selfShare ?? 1) * 100),
|
|
61
|
+
);
|
|
62
|
+
return (
|
|
63
|
+
<span className="grid gap-3">
|
|
64
|
+
<span
|
|
65
|
+
className={cn(
|
|
66
|
+
"grid gap-2.5",
|
|
67
|
+
(props.sections.length > 0 || props.footer) &&
|
|
68
|
+
"border-b border-dashboard-border pb-3",
|
|
69
|
+
)}
|
|
70
|
+
>
|
|
71
|
+
<span className="flex items-baseline justify-between gap-3">
|
|
72
|
+
<span className="min-w-0 truncate">
|
|
73
|
+
{props.title}
|
|
74
|
+
{props.note ? (
|
|
75
|
+
<span className="text-dashboard-text-faint"> · {props.note}</span>
|
|
76
|
+
) : null}
|
|
77
|
+
</span>
|
|
78
|
+
<span className="whitespace-nowrap text-lg font-semibold tabular-nums text-dashboard-text">
|
|
79
|
+
{props.total}
|
|
80
|
+
</span>
|
|
81
|
+
</span>
|
|
82
|
+
{props.split ? (
|
|
83
|
+
<>
|
|
84
|
+
<span
|
|
85
|
+
aria-hidden="true"
|
|
86
|
+
className="flex h-1.5 overflow-hidden rounded-full bg-dashboard-fill-hover"
|
|
87
|
+
>
|
|
88
|
+
<span
|
|
89
|
+
className={SELF_FILL}
|
|
90
|
+
style={{ width: `${selfPercent}%` }}
|
|
91
|
+
/>
|
|
92
|
+
<span
|
|
93
|
+
className={SUBAGENT_FILL}
|
|
94
|
+
style={{ width: `${100 - selfPercent}%` }}
|
|
95
|
+
/>
|
|
96
|
+
</span>
|
|
97
|
+
<span className="flex flex-wrap justify-between gap-x-3 gap-y-1 tabular-nums">
|
|
98
|
+
<span className="inline-flex items-center gap-1.5 whitespace-nowrap">
|
|
99
|
+
<Swatch className={SELF_FILL} />
|
|
100
|
+
this agent
|
|
101
|
+
<span className="font-medium text-dashboard-text">
|
|
102
|
+
{props.split.self}
|
|
103
|
+
</span>
|
|
104
|
+
</span>
|
|
105
|
+
<span className="inline-flex items-center gap-1.5 whitespace-nowrap">
|
|
106
|
+
<Swatch className={SUBAGENT_FILL} />
|
|
107
|
+
{props.split.count} subagent{props.split.count === 1 ? "" : "s"}
|
|
108
|
+
<span className="font-medium text-dashboard-text">
|
|
109
|
+
{props.split.subagents}
|
|
110
|
+
</span>
|
|
111
|
+
</span>
|
|
112
|
+
</span>
|
|
113
|
+
</>
|
|
114
|
+
) : null}
|
|
115
|
+
</span>
|
|
116
|
+
{props.sections.map((section) => (
|
|
117
|
+
<span
|
|
118
|
+
className="grid grid-cols-[minmax(0,1fr)_auto] gap-x-3 gap-y-2"
|
|
119
|
+
key={section.title}
|
|
120
|
+
>
|
|
121
|
+
<span className="col-span-2 font-sans font-medium text-dashboard-text-faint">
|
|
122
|
+
{section.title}
|
|
123
|
+
{section.total ? ` · ${section.total}` : null}
|
|
124
|
+
</span>
|
|
125
|
+
{section.rows.map((row) => (
|
|
126
|
+
<span className="contents" key={row.label}>
|
|
127
|
+
<span
|
|
128
|
+
className={cn(
|
|
129
|
+
"flex min-w-0 items-baseline gap-2",
|
|
130
|
+
row.code && "font-mono text-dashboard-text",
|
|
131
|
+
)}
|
|
132
|
+
>
|
|
133
|
+
<span className="min-w-0 truncate" title={row.label}>
|
|
134
|
+
{row.label}
|
|
135
|
+
</span>
|
|
136
|
+
{row.live ? (
|
|
137
|
+
<span className="shrink-0 font-sans text-2xs text-dashboard-text-muted">
|
|
138
|
+
<ShimmerText active>in progress</ShimmerText>
|
|
139
|
+
</span>
|
|
140
|
+
) : null}
|
|
141
|
+
</span>
|
|
142
|
+
<span className="whitespace-nowrap text-right tabular-nums text-dashboard-text">
|
|
143
|
+
{row.value}
|
|
144
|
+
</span>
|
|
145
|
+
</span>
|
|
146
|
+
))}
|
|
147
|
+
{section.more ? (
|
|
148
|
+
<>
|
|
149
|
+
<span className="text-dashboard-text-faint">
|
|
150
|
+
{section.more.count} more
|
|
151
|
+
</span>
|
|
152
|
+
<span className="whitespace-nowrap text-right tabular-nums">
|
|
153
|
+
{section.more.value}
|
|
154
|
+
</span>
|
|
155
|
+
</>
|
|
156
|
+
) : null}
|
|
157
|
+
</span>
|
|
158
|
+
))}
|
|
159
|
+
{props.footer ? (
|
|
160
|
+
<span
|
|
161
|
+
className={cn(
|
|
162
|
+
"text-dashboard-text-faint",
|
|
163
|
+
props.sections.length > 0 &&
|
|
164
|
+
"border-t border-dashboard-border pt-3",
|
|
165
|
+
)}
|
|
166
|
+
>
|
|
167
|
+
{props.footer}
|
|
168
|
+
</span>
|
|
169
|
+
) : null}
|
|
170
|
+
</span>
|
|
171
|
+
);
|
|
172
|
+
}
|
|
@@ -352,8 +352,12 @@ export function transcriptMessagesFromEvents(
|
|
|
352
352
|
if (data.type === "subagent") {
|
|
353
353
|
const subagentId = `${data.childConversationId}:${data.startedSeq}`;
|
|
354
354
|
const existing = subagents.get(subagentId);
|
|
355
|
+
const finishedTimestamp =
|
|
356
|
+
data.status === "running" ? undefined : eventTimestamp(event);
|
|
355
357
|
if (existing) {
|
|
356
358
|
existing.status = data.status;
|
|
359
|
+
if (finishedTimestamp === undefined) delete existing.finishedTimestamp;
|
|
360
|
+
else existing.finishedTimestamp = finishedTimestamp;
|
|
357
361
|
continue;
|
|
358
362
|
}
|
|
359
363
|
const part = {
|
|
@@ -362,6 +366,9 @@ export function transcriptMessagesFromEvents(
|
|
|
362
366
|
childConversationId: data.childConversationId,
|
|
363
367
|
subagentKind: data.subagentKind,
|
|
364
368
|
status: data.status,
|
|
369
|
+
...(finishedTimestamp === undefined
|
|
370
|
+
? undefined
|
|
371
|
+
: { finishedTimestamp }),
|
|
365
372
|
...(data.agentName ? { agentName: data.agentName } : undefined),
|
|
366
373
|
...(data.task ? { task: data.task } : undefined),
|
|
367
374
|
...(data.title ? { title: data.title } : undefined),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export const TRANSCRIPT_ANCHOR_CLASS =
|
|
2
|
-
"font-medium text-
|
|
2
|
+
"font-medium text-dashboard-accent-text underline decoration-dashboard-accent/35 underline-offset-2 transition-colors hover:text-dashboard-text hover:decoration-dashboard-text-solid";
|
|
3
3
|
|
|
4
4
|
export type TranscriptMarkdownLink = {
|
|
5
5
|
end: number;
|
|
@@ -36,9 +36,7 @@ export function findTranscriptMarkdownLinks(
|
|
|
36
36
|
...markdownLinks,
|
|
37
37
|
...autolinks,
|
|
38
38
|
...findBareLinks(text, bareRanges),
|
|
39
|
-
].sort(
|
|
40
|
-
(left, right) => left.start - right.start || left.end - right.end,
|
|
41
|
-
);
|
|
39
|
+
].sort((left, right) => left.start - right.start || left.end - right.end);
|
|
42
40
|
}
|
|
43
41
|
|
|
44
42
|
function findMarkdownLinks(
|
|
@@ -5,6 +5,6 @@ export function transcriptEmptyClass(
|
|
|
5
5
|
const colors =
|
|
6
6
|
tone === "error"
|
|
7
7
|
? "border-rose-300/25 bg-rose-300/[0.07] text-rose-100"
|
|
8
|
-
: "border-
|
|
8
|
+
: "border-dashboard-border bg-dashboard-fill-soft text-dashboard-text-muted";
|
|
9
9
|
return `rounded-lg border p-5 text-sm leading-relaxed ${colors}`;
|
|
10
10
|
}
|
package/src/client/format.ts
CHANGED
|
@@ -919,6 +919,7 @@ export function buildConversations(
|
|
|
919
919
|
channel: summary.channel,
|
|
920
920
|
channelName: summary.channelName,
|
|
921
921
|
channelNameRedacted: summary.channelNameRedacted,
|
|
922
|
+
childAgentTotals: summary.childAgentTotals,
|
|
922
923
|
cumulativeDurationMs: summary.cumulativeDurationMs,
|
|
923
924
|
cumulativeUsage: summary.cumulativeUsage,
|
|
924
925
|
displayTitle: summary.displayTitle,
|
|
@@ -110,11 +110,11 @@ export function PersonalTokensPage() {
|
|
|
110
110
|
|
|
111
111
|
<Card className="mb-0 mt-6" padding="md" variant="raised">
|
|
112
112
|
{createdToken ? (
|
|
113
|
-
<div className="mt-5 rounded border border-emerald-400/40 bg-emerald-400/5 p-3">
|
|
113
|
+
<div className="mt-5 rounded-md border border-emerald-400/40 bg-emerald-400/5 p-3">
|
|
114
114
|
<p className="mt-0 mb-2 text-sm font-semibold">
|
|
115
115
|
Copy this token now. It won't be shown again.
|
|
116
116
|
</p>
|
|
117
|
-
<code className="block overflow-x-auto rounded bg-
|
|
117
|
+
<code className="block overflow-x-auto rounded-md bg-dashboard-ink p-2 text-xs text-emerald-300">
|
|
118
118
|
{createdToken.token}
|
|
119
119
|
</code>
|
|
120
120
|
<Button
|
|
@@ -166,10 +166,10 @@ export function PersonalTokensPage() {
|
|
|
166
166
|
) : (
|
|
167
167
|
tokens.map((token) => (
|
|
168
168
|
<div
|
|
169
|
-
className="flex items-center gap-3 rounded border border-
|
|
169
|
+
className="flex items-center gap-3 rounded-md border border-dashboard-border-strong p-3"
|
|
170
170
|
key={token.id}
|
|
171
171
|
>
|
|
172
|
-
<KeyRound className="text-
|
|
172
|
+
<KeyRound className="text-dashboard-accent" size={16} />
|
|
173
173
|
<div className="min-w-0 flex-1">
|
|
174
174
|
<p className="m-0 truncate text-sm font-semibold">
|
|
175
175
|
{token.name}
|
|
@@ -31,7 +31,7 @@ export function AdminPage(props: { pages: PluginUserPageLink[] }) {
|
|
|
31
31
|
{adminPages.length === 0 ? (
|
|
32
32
|
<Card padding="md">
|
|
33
33
|
<div className="flex items-center gap-4">
|
|
34
|
-
<div className="grid size-10 shrink-0 place-items-center rounded border border-
|
|
34
|
+
<div className="grid size-10 shrink-0 place-items-center rounded-md border border-dashboard-border bg-dashboard-fill-soft text-dashboard-text-muted">
|
|
35
35
|
<Boxes aria-hidden="true" size={17} />
|
|
36
36
|
</div>
|
|
37
37
|
<p className="m-0 text-sm text-dashboard-text-muted">
|
|
@@ -50,7 +50,7 @@ export function AdminPage(props: { pages: PluginUserPageLink[] }) {
|
|
|
50
50
|
<Card padding="md">
|
|
51
51
|
<div className="flex items-center gap-3">
|
|
52
52
|
<div className="min-w-0 flex-1">
|
|
53
|
-
<div className="font-
|
|
53
|
+
<div className="font-sans font-medium text-xs text-dashboard-text-muted">
|
|
54
54
|
{page.pluginDisplayName}
|
|
55
55
|
</div>
|
|
56
56
|
<h2 className="mt-1 mb-0 font-display text-base font-medium text-dashboard-text">
|
|
@@ -45,7 +45,7 @@ export function AutomationCostChart(props: {
|
|
|
45
45
|
<h2 className="m-0 font-display text-xl font-medium text-dashboard-text">
|
|
46
46
|
{formatCostSummary({ total }) || "$0.00"}
|
|
47
47
|
</h2>
|
|
48
|
-
<p className="mt-1 mb-0 font-
|
|
48
|
+
<p className="mt-1 mb-0 font-sans text-xs leading-relaxed text-dashboard-text-muted">
|
|
49
49
|
Spend from conversations linked to completed automation executions.
|
|
50
50
|
</p>
|
|
51
51
|
</div>
|
|
@@ -112,7 +112,7 @@ export function AutomationCostChart(props: {
|
|
|
112
112
|
/>
|
|
113
113
|
</ChartSvg>
|
|
114
114
|
{!hasCost ? (
|
|
115
|
-
<div className="pointer-events-none absolute inset-0 grid place-items-center pt-12 font-
|
|
115
|
+
<div className="pointer-events-none absolute inset-0 grid place-items-center pt-12 font-sans text-xs text-dashboard-text-muted">
|
|
116
116
|
No linked spend in this period.
|
|
117
117
|
</div>
|
|
118
118
|
) : null}
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
import { conversationPath } from "../../conversations/conversationRoutes";
|
|
18
18
|
import { formatTime, peoplePath } from "../../format";
|
|
19
19
|
import { TranscriptText } from "../../conversations/TranscriptText";
|
|
20
|
+
import { cn, dashboardInlineLinkClass } from "../../styles";
|
|
20
21
|
|
|
21
22
|
/** Show one automation's instruction and metadata in a right-side slide-out. */
|
|
22
23
|
export function AutomationDetailsDrawer(props: {
|
|
@@ -30,7 +31,7 @@ export function AutomationDetailsDrawer(props: {
|
|
|
30
31
|
const { automation } = props;
|
|
31
32
|
const createdBy = automation.createdByEmail ? (
|
|
32
33
|
<Link
|
|
33
|
-
className="font-semibold
|
|
34
|
+
className={cn("font-semibold", dashboardInlineLinkClass)}
|
|
34
35
|
to={peoplePath(automation.createdByEmail)}
|
|
35
36
|
>
|
|
36
37
|
{automation.ownedByViewer ? "you" : automation.createdBy}
|
|
@@ -175,10 +176,7 @@ function AutomationExecutionSummary(props: {
|
|
|
175
176
|
return (
|
|
176
177
|
<div className="text-sm text-dashboard-text-muted">
|
|
177
178
|
{automation.totalRuns > 0 ? (
|
|
178
|
-
<Link
|
|
179
|
-
className="text-dashboard-text underline decoration-white/20 underline-offset-2 hover:decoration-white/60"
|
|
180
|
-
to={executionsPath}
|
|
181
|
-
>
|
|
179
|
+
<Link className={dashboardInlineLinkClass} to={executionsPath}>
|
|
182
180
|
{runCount} runs / {rangeLabel}
|
|
183
181
|
</Link>
|
|
184
182
|
) : (
|
|
@@ -189,10 +187,7 @@ function AutomationExecutionSummary(props: {
|
|
|
189
187
|
<span className="mx-2 opacity-45">·</span>
|
|
190
188
|
<span>
|
|
191
189
|
{automation.totalRuns > 0 ? (
|
|
192
|
-
<Link
|
|
193
|
-
className="text-dashboard-text underline decoration-white/20 underline-offset-2 hover:decoration-white/60"
|
|
194
|
-
to={executionsPath}
|
|
195
|
-
>
|
|
190
|
+
<Link className={dashboardInlineLinkClass} to={executionsPath}>
|
|
196
191
|
{automation.totalRuns} total
|
|
197
192
|
</Link>
|
|
198
193
|
) : (
|
|
@@ -201,7 +196,7 @@ function AutomationExecutionSummary(props: {
|
|
|
201
196
|
{automation.lastRunAt ? " · Last run " : " · Never run"}
|
|
202
197
|
{automation.lastRunAt && automation.lastConversationId ? (
|
|
203
198
|
<Link
|
|
204
|
-
className=
|
|
199
|
+
className={dashboardInlineLinkClass}
|
|
205
200
|
to={conversationPath(automation.lastConversationId)}
|
|
206
201
|
>
|
|
207
202
|
{formatAutomationRunTime(automation.lastRunAt)}
|
|
@@ -425,7 +425,7 @@ export function AutomationEditor(props: {
|
|
|
425
425
|
<div className="flex shrink-0 gap-2">
|
|
426
426
|
<Link
|
|
427
427
|
to={props.returnPath}
|
|
428
|
-
className="inline-flex min-h-11 items-center rounded border border-dashboard-border-emphasis px-3 text-sm text-dashboard-text no-underline sm:min-h-9"
|
|
428
|
+
className="inline-flex min-h-11 items-center rounded-md border border-dashboard-border-emphasis px-3 text-sm text-dashboard-text no-underline sm:min-h-9"
|
|
429
429
|
>
|
|
430
430
|
Cancel
|
|
431
431
|
</Link>
|
|
@@ -45,7 +45,7 @@ export function AutomationExecutionChart(props: {
|
|
|
45
45
|
<h2 className="m-0 font-display text-xl font-medium text-dashboard-text">
|
|
46
46
|
{totals.reduce((sum, value) => sum + value, 0).toLocaleString()} runs
|
|
47
47
|
</h2>
|
|
48
|
-
<p className="mt-1 mb-0 font-
|
|
48
|
+
<p className="mt-1 mb-0 font-sans text-xs leading-relaxed text-dashboard-text-muted">
|
|
49
49
|
Completed automation executions over time.
|
|
50
50
|
</p>
|
|
51
51
|
</div>
|
|
@@ -104,7 +104,7 @@ export function AutomationExecutionChart(props: {
|
|
|
104
104
|
/>
|
|
105
105
|
</ChartSvg>
|
|
106
106
|
{!hasExecutions ? (
|
|
107
|
-
<div className="pointer-events-none absolute inset-0 grid place-items-center pt-12 font-
|
|
107
|
+
<div className="pointer-events-none absolute inset-0 grid place-items-center pt-12 font-sans text-xs text-dashboard-text-muted">
|
|
108
108
|
No automation executions in this period.
|
|
109
109
|
</div>
|
|
110
110
|
) : null}
|
|
@@ -44,7 +44,7 @@ export function AutomationExecutionStatusChart(props: {
|
|
|
44
44
|
<h2 className="m-0 font-display text-xl font-medium text-dashboard-text">
|
|
45
45
|
Executions over time
|
|
46
46
|
</h2>
|
|
47
|
-
<p className="mt-1 mb-0 font-
|
|
47
|
+
<p className="mt-1 mb-0 font-sans text-xs leading-relaxed text-dashboard-text-muted">
|
|
48
48
|
{bucketUnit === "hour"
|
|
49
49
|
? "Terminal runs for this automation each hour."
|
|
50
50
|
: bucketUnit === "6hour"
|
|
@@ -121,7 +121,7 @@ export function AutomationExecutionStatusChart(props: {
|
|
|
121
121
|
/>
|
|
122
122
|
</ChartSvg>
|
|
123
123
|
{!hasExecutions ? (
|
|
124
|
-
<div className="pointer-events-none absolute inset-0 grid place-items-center pt-12 font-
|
|
124
|
+
<div className="pointer-events-none absolute inset-0 grid place-items-center pt-12 font-sans text-xs text-dashboard-text-muted">
|
|
125
125
|
No automation executions in this period.
|
|
126
126
|
</div>
|
|
127
127
|
) : null}
|
|
@@ -87,7 +87,7 @@ export function AutomationExecutionsPage(props: { enabled: boolean }) {
|
|
|
87
87
|
: "Automation executions could not be loaded. Try again."}
|
|
88
88
|
</InlineError>
|
|
89
89
|
<Link
|
|
90
|
-
className="mt-3 inline-flex items-center gap-2 font-
|
|
90
|
+
className="mt-3 inline-flex items-center gap-2 font-sans text-xs text-dashboard-text-muted no-underline hover:text-dashboard-text"
|
|
91
91
|
to={
|
|
92
92
|
automationId ? automationPath(automationId) : "/automations/list"
|
|
93
93
|
}
|
|
@@ -122,7 +122,7 @@ function AutomationExecutionsView(props: {
|
|
|
122
122
|
<>
|
|
123
123
|
<div>
|
|
124
124
|
<Link
|
|
125
|
-
className="mb-3 inline-flex items-center gap-2 font-
|
|
125
|
+
className="mb-3 inline-flex items-center gap-2 font-sans text-xs text-dashboard-text-muted no-underline hover:text-dashboard-text"
|
|
126
126
|
to={props.backTo}
|
|
127
127
|
>
|
|
128
128
|
<ArrowLeft aria-hidden="true" size={14} />
|
|
@@ -177,7 +177,7 @@ function AutomationExecutionsView(props: {
|
|
|
177
177
|
<div className="min-w-[36rem]">
|
|
178
178
|
<div
|
|
179
179
|
className={cn(
|
|
180
|
-
"sticky top-0 z-[1] hidden items-center gap-4 border-b border-dashboard-border-subtle bg-dashboard-overlay-soft px-4 py-2.5 font-
|
|
180
|
+
"sticky top-0 z-[1] hidden items-center gap-4 border-b border-dashboard-border-subtle bg-dashboard-overlay-soft px-4 py-2.5 font-sans font-medium text-xs text-dashboard-text-muted md:grid",
|
|
181
181
|
EXECUTION_GRID,
|
|
182
182
|
)}
|
|
183
183
|
role="row"
|
|
@@ -290,7 +290,7 @@ function MetricCell(props: { label: string; value: string }) {
|
|
|
290
290
|
<div className="min-w-0 max-md:flex max-md:items-center max-md:gap-2">
|
|
291
291
|
<div
|
|
292
292
|
aria-hidden="true"
|
|
293
|
-
className="mb-1 hidden font-
|
|
293
|
+
className="mb-1 hidden font-sans font-medium text-2xs text-dashboard-text-muted max-md:mb-0 max-md:block"
|
|
294
294
|
>
|
|
295
295
|
{props.label}
|
|
296
296
|
</div>
|
|
@@ -58,7 +58,7 @@ export function AutomationRow(props: {
|
|
|
58
58
|
<button
|
|
59
59
|
aria-expanded={props.selected}
|
|
60
60
|
aria-label={`View automation details: ${automation.title}`}
|
|
61
|
-
className="block w-full min-w-0 cursor-pointer rounded border-0 bg-transparent p-0 text-left focus-visible:outline focus-visible:outline-2 focus-visible:outline-dashboard-focus"
|
|
61
|
+
className="block w-full min-w-0 cursor-pointer rounded-md border-0 bg-transparent p-0 text-left focus-visible:outline focus-visible:outline-2 focus-visible:outline-dashboard-focus"
|
|
62
62
|
onClick={props.onSelect}
|
|
63
63
|
type="button"
|
|
64
64
|
>
|
|
@@ -88,7 +88,7 @@ export function AutomationRow(props: {
|
|
|
88
88
|
<div className="mt-2.5 flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1 text-xs text-dashboard-text-muted">
|
|
89
89
|
{automation.createdByEmail ? (
|
|
90
90
|
<Link
|
|
91
|
-
className="inline-flex min-w-0 max-w-full items-center gap-2 rounded text-dashboard-text no-underline hover:underline focus-visible:outline focus-visible:outline-2 focus-visible:outline-dashboard-focus"
|
|
91
|
+
className="inline-flex min-w-0 max-w-full items-center gap-2 rounded-md text-dashboard-text no-underline hover:underline focus-visible:outline focus-visible:outline-2 focus-visible:outline-dashboard-focus"
|
|
92
92
|
title={automation.createdBy}
|
|
93
93
|
to={peoplePath(automation.createdByEmail)}
|
|
94
94
|
>
|
|
@@ -320,12 +320,12 @@ function AutomationActions(props: {
|
|
|
320
320
|
<Link
|
|
321
321
|
role="menuitem"
|
|
322
322
|
to={props.editPath}
|
|
323
|
-
className="flex min-h-11 items-center rounded px-3 text-sm text-dashboard-text no-underline hover:bg-dashboard-fill-hover focus-visible:outline focus-visible:outline-dashboard-focus"
|
|
323
|
+
className="flex min-h-11 items-center rounded-md px-3 text-sm text-dashboard-text no-underline hover:bg-dashboard-fill-hover focus-visible:outline focus-visible:outline-dashboard-focus"
|
|
324
324
|
>
|
|
325
325
|
Edit automation
|
|
326
326
|
</Link>
|
|
327
327
|
<button
|
|
328
|
-
className="flex min-h-11 w-full cursor-pointer items-center gap-2 rounded border-0 bg-transparent px-3 text-sm text-rose-300 hover:bg-dashboard-fill-hover focus-visible:bg-dashboard-fill-hover focus-visible:outline focus-visible:outline-2 focus-visible:outline-dashboard-focus"
|
|
328
|
+
className="flex min-h-11 w-full cursor-pointer items-center gap-2 rounded-md border-0 bg-transparent px-3 text-sm text-rose-300 hover:bg-dashboard-fill-hover focus-visible:bg-dashboard-fill-hover focus-visible:outline focus-visible:outline-2 focus-visible:outline-dashboard-focus"
|
|
329
329
|
onClick={() => {
|
|
330
330
|
close();
|
|
331
331
|
props.onDelete();
|
|
@@ -156,7 +156,7 @@ export function AutomationRunsPage(props: { enabled: boolean }) {
|
|
|
156
156
|
<div className="min-w-[44rem]">
|
|
157
157
|
<div
|
|
158
158
|
className={cn(
|
|
159
|
-
"sticky top-0 z-[1] hidden items-center gap-4 border-b border-dashboard-border-subtle bg-dashboard-overlay-soft px-4 py-2.5 font-
|
|
159
|
+
"sticky top-0 z-[1] hidden items-center gap-4 border-b border-dashboard-border-subtle bg-dashboard-overlay-soft px-4 py-2.5 font-sans font-medium text-xs text-dashboard-text-muted md:grid",
|
|
160
160
|
RUN_GRID,
|
|
161
161
|
)}
|
|
162
162
|
role="row"
|
|
@@ -278,7 +278,7 @@ function MetricCell(props: { label: string; value: string }) {
|
|
|
278
278
|
<div className="min-w-0 max-md:flex max-md:items-center max-md:gap-2">
|
|
279
279
|
<div
|
|
280
280
|
aria-hidden="true"
|
|
281
|
-
className="mb-1 hidden font-
|
|
281
|
+
className="mb-1 hidden font-sans font-medium text-2xs text-dashboard-text-muted max-md:mb-0 max-md:block"
|
|
282
282
|
>
|
|
283
283
|
{props.label}
|
|
284
284
|
</div>
|
|
@@ -297,7 +297,7 @@ function AutomationKindIcon(props: { kind: AutomationRun["kind"] }) {
|
|
|
297
297
|
return (
|
|
298
298
|
<span
|
|
299
299
|
aria-label={label}
|
|
300
|
-
className="inline-flex size-3.5 shrink-0 items-center justify-center text-
|
|
300
|
+
className="inline-flex size-3.5 shrink-0 items-center justify-center text-dashboard-accent/80"
|
|
301
301
|
role="img"
|
|
302
302
|
title={label}
|
|
303
303
|
>
|
|
@@ -152,7 +152,7 @@ export function AutomationScheduleFields(props: {
|
|
|
152
152
|
})
|
|
153
153
|
}
|
|
154
154
|
className={cn(
|
|
155
|
-
"min-h-11 cursor-pointer rounded border px-1 text-xs font-medium capitalize focus-visible:outline-2 focus-visible:outline-dashboard-focus sm:min-h-10 sm:text-sm",
|
|
155
|
+
"min-h-11 cursor-pointer rounded-md border px-1 text-xs font-medium capitalize focus-visible:outline-2 focus-visible:outline-dashboard-focus sm:min-h-10 sm:text-sm",
|
|
156
156
|
value.weekdays?.includes(day)
|
|
157
157
|
? "border-dashboard-focus/50 bg-dashboard-focus/10 text-dashboard-focus"
|
|
158
158
|
: "border-dashboard-border-emphasis text-dashboard-text-muted hover:bg-dashboard-fill-hover",
|
|
@@ -77,7 +77,7 @@ export function AutomationVersionsPage(props: { enabled: boolean }) {
|
|
|
77
77
|
function BackLink(props: { to: string }) {
|
|
78
78
|
return (
|
|
79
79
|
<Link
|
|
80
|
-
className="mb-3 inline-flex items-center gap-2 font-
|
|
80
|
+
className="mb-3 inline-flex items-center gap-2 font-sans text-xs text-dashboard-text-muted no-underline hover:text-dashboard-text"
|
|
81
81
|
to={props.to}
|
|
82
82
|
>
|
|
83
83
|
<ArrowLeft aria-hidden="true" size={14} />
|