@sentry/junior-dashboard 0.248.0 → 0.250.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/README.md +3 -0
- package/dist/app.js +2 -2
- package/dist/client.js +40 -38
- package/dist/index.js +2 -2
- package/dist/tailwind.css +1 -1
- package/package.json +3 -3
- package/src/client/App.tsx +19 -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 +4 -4
- 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 +17 -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 +7 -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 +10 -10
- package/src/client/conversations/ConversationPage.tsx +2 -1
- package/src/client/conversations/ConversationSidebar.tsx +6 -6
- package/src/client/conversations/ConversationUsageBreakdown.tsx +4 -4
- 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/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 +1 -1
- 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/pages/ConnectionsPage.tsx +207 -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/ChartFixtures.tsx +265 -21
- 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 +2 -0
- package/src/tailwind.css +36 -38
|
@@ -13,19 +13,19 @@ export function DirectoryRowsSkeleton(props: { wideRuntime?: boolean }) {
|
|
|
13
13
|
{Array.from({ length: 5 }, (_, index) => (
|
|
14
14
|
<div
|
|
15
15
|
aria-hidden="true"
|
|
16
|
-
className={`grid min-w-0 ${gridColumns} items-center gap-4 border-b border-
|
|
16
|
+
className={`grid min-w-0 ${gridColumns} items-center gap-4 border-b border-dashboard-border-subtle px-4 py-3.5 last:border-b-0 max-md:gap-x-3 max-md:gap-y-4`}
|
|
17
17
|
key={index}
|
|
18
18
|
>
|
|
19
19
|
<div className="flex min-w-0 items-center gap-3 max-md:col-span-3">
|
|
20
|
-
<span className="size-9 shrink-0 rounded bg-
|
|
20
|
+
<span className="size-9 shrink-0 rounded-md bg-dashboard-fill-hover" />
|
|
21
21
|
<div className="grid min-w-0 flex-1 gap-2">
|
|
22
|
-
<span className="h-3.5 w-2/5 rounded bg-
|
|
23
|
-
<span className="h-2.5 w-3/5 rounded bg-
|
|
22
|
+
<span className="h-3.5 w-2/5 rounded-md bg-dashboard-fill-strong" />
|
|
23
|
+
<span className="h-2.5 w-3/5 rounded-md bg-dashboard-fill-soft" />
|
|
24
24
|
</div>
|
|
25
25
|
</div>
|
|
26
26
|
{[0, 1, 2].map((metric) => (
|
|
27
27
|
<span
|
|
28
|
-
className="h-4 w-10 justify-self-end rounded bg-
|
|
28
|
+
className="h-4 w-10 justify-self-end rounded-md bg-dashboard-fill-hover"
|
|
29
29
|
key={metric}
|
|
30
30
|
/>
|
|
31
31
|
))}
|
|
@@ -43,7 +43,7 @@ export function DirectoryTable(props: {
|
|
|
43
43
|
<div
|
|
44
44
|
aria-hidden="true"
|
|
45
45
|
className={cn(
|
|
46
|
-
"grid items-center gap-4 border-b border-dashboard-border-subtle bg-dashboard-overlay-soft px-4 py-2.5 font-
|
|
46
|
+
"grid 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 max-md:hidden",
|
|
47
47
|
directoryGridClass,
|
|
48
48
|
)}
|
|
49
49
|
>
|
|
@@ -84,7 +84,7 @@ export function DirectoryIdentity(props: {
|
|
|
84
84
|
<div className="flex min-w-0 items-center gap-3 max-md:col-span-3">
|
|
85
85
|
<span
|
|
86
86
|
className={cn(
|
|
87
|
-
"grid size-9 shrink-0 place-items-center rounded border border-
|
|
87
|
+
"grid size-9 shrink-0 place-items-center rounded-md border border-dashboard-border-strong transition-colors",
|
|
88
88
|
props.iconClassName,
|
|
89
89
|
)}
|
|
90
90
|
>
|
|
@@ -95,7 +95,7 @@ export function DirectoryIdentity(props: {
|
|
|
95
95
|
{props.title}
|
|
96
96
|
</div>
|
|
97
97
|
{props.description ? (
|
|
98
|
-
<div className="mt-1 truncate font-
|
|
98
|
+
<div className="mt-1 truncate font-sans text-xs leading-tight text-dashboard-text-muted">
|
|
99
99
|
{props.description}
|
|
100
100
|
</div>
|
|
101
101
|
) : null}
|
|
@@ -12,22 +12,22 @@ export function CardHeader(props: {
|
|
|
12
12
|
return (
|
|
13
13
|
<div
|
|
14
14
|
className={cn(
|
|
15
|
-
"flex flex-wrap items-start justify-between gap-4 border-b border-
|
|
15
|
+
"flex flex-wrap items-start justify-between gap-4 border-b border-dashboard-border-subtle px-4 py-4 sm:px-5",
|
|
16
16
|
props.className,
|
|
17
17
|
)}
|
|
18
18
|
>
|
|
19
19
|
<div>
|
|
20
|
-
<h3 className="m-0 font-
|
|
20
|
+
<h3 className="m-0 font-sans text-xs font-medium text-dashboard-text-muted">
|
|
21
21
|
{props.title}
|
|
22
22
|
</h3>
|
|
23
23
|
{props.description ? (
|
|
24
|
-
<p className="mt-1 mb-0 font-
|
|
24
|
+
<p className="mt-1 mb-0 font-sans text-xs leading-relaxed text-dashboard-text-muted">
|
|
25
25
|
{props.description}
|
|
26
26
|
</p>
|
|
27
27
|
) : null}
|
|
28
28
|
</div>
|
|
29
29
|
{props.trailing ? (
|
|
30
|
-
<div className="font-
|
|
30
|
+
<div className="font-sans text-xs text-dashboard-text-muted">
|
|
31
31
|
{props.trailing}
|
|
32
32
|
</div>
|
|
33
33
|
) : null}
|
|
@@ -101,7 +101,11 @@ export function DashboardChromeProvider(props: { children: ReactNode }) {
|
|
|
101
101
|
);
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
/**
|
|
104
|
+
/**
|
|
105
|
+
* Sticky shell chrome: primary header, secondary navigation slot, and banner.
|
|
106
|
+
* One bottom border closes the header and page links, so page link
|
|
107
|
+
* underlines sit on it. Banners render below that border.
|
|
108
|
+
*/
|
|
105
109
|
export function DashboardChrome(props: {
|
|
106
110
|
banner?: ReactNode;
|
|
107
111
|
header: ReactNode;
|
|
@@ -113,8 +117,10 @@ export function DashboardChrome(props: {
|
|
|
113
117
|
|
|
114
118
|
return (
|
|
115
119
|
<div className="sticky top-0 z-30 bg-dashboard-bg/95 pt-[env(safe-area-inset-top)]">
|
|
116
|
-
|
|
117
|
-
|
|
120
|
+
<div className="border-b border-dashboard-border-strong">
|
|
121
|
+
{props.header}
|
|
122
|
+
<div className="hidden md:block" ref={chrome.secondarySlotRef} />
|
|
123
|
+
</div>
|
|
118
124
|
{props.banner}
|
|
119
125
|
</div>
|
|
120
126
|
);
|
|
@@ -74,14 +74,14 @@ export function DashboardHeader(props: {
|
|
|
74
74
|
cn(
|
|
75
75
|
"shrink-0 whitespace-nowrap rounded-lg px-3 py-2 font-sans text-sm font-medium tracking-normal no-underline transition-colors",
|
|
76
76
|
isActive
|
|
77
|
-
? "bg-
|
|
77
|
+
? "bg-dashboard-accent/[0.1] text-dashboard-accent-text"
|
|
78
78
|
: cn("hover:bg-dashboard-fill-soft", dashboardInteractiveTextClass),
|
|
79
79
|
);
|
|
80
80
|
const sheetLinkClass = ({ isActive }: { isActive: boolean }) =>
|
|
81
81
|
cn(
|
|
82
|
-
"rounded-lg px-3 py-3 font-
|
|
82
|
+
"rounded-lg px-3 py-3 font-sans text-sm font-medium no-underline transition-colors",
|
|
83
83
|
isActive
|
|
84
|
-
? "bg-
|
|
84
|
+
? "bg-dashboard-accent/[0.1] text-dashboard-accent-text"
|
|
85
85
|
: cn("hover:bg-dashboard-fill-soft", dashboardInteractiveTextClass),
|
|
86
86
|
);
|
|
87
87
|
|
|
@@ -148,7 +148,7 @@ export function DashboardHeader(props: {
|
|
|
148
148
|
}, [props.mobileNavigationOpen]);
|
|
149
149
|
|
|
150
150
|
return (
|
|
151
|
-
<header className="relative
|
|
151
|
+
<header className="relative bg-dashboard-bg">
|
|
152
152
|
<div
|
|
153
153
|
className={cn(
|
|
154
154
|
props.compact ? "w-full min-w-0" : dashboardContainerClass,
|
|
@@ -200,7 +200,7 @@ export function DashboardHeader(props: {
|
|
|
200
200
|
)}
|
|
201
201
|
to="/"
|
|
202
202
|
>
|
|
203
|
-
<span className="truncate font-
|
|
203
|
+
<span className="truncate font-sans text-sm font-semibold md:hidden">
|
|
204
204
|
{getDashboardAgentName()}
|
|
205
205
|
</span>
|
|
206
206
|
<span className="hidden md:block">
|
|
@@ -252,7 +252,7 @@ export function DashboardHeader(props: {
|
|
|
252
252
|
<div className="flex items-center justify-between gap-3 border-b border-dashboard-border-subtle bg-dashboard-surface-raised px-3 py-2 pt-[max(0.5rem,env(safe-area-inset-top))]">
|
|
253
253
|
<Link
|
|
254
254
|
aria-label={`${getDashboardAgentName()} home`}
|
|
255
|
-
className="min-w-0 truncate font-
|
|
255
|
+
className="min-w-0 truncate font-sans text-sm font-semibold text-inherit no-underline"
|
|
256
256
|
to="/"
|
|
257
257
|
>
|
|
258
258
|
{getDashboardAgentName()}
|
|
@@ -307,7 +307,7 @@ export function DashboardHeader(props: {
|
|
|
307
307
|
</div>
|
|
308
308
|
) : null}
|
|
309
309
|
{props.version ? (
|
|
310
|
-
<p className="m-0 font-
|
|
310
|
+
<p className="m-0 font-sans text-xs text-dashboard-text-muted">
|
|
311
311
|
junior version {props.version}
|
|
312
312
|
</p>
|
|
313
313
|
) : null}
|
|
@@ -36,12 +36,12 @@ export function PageHeader(props: {
|
|
|
36
36
|
const actions = props.actions ?? rangeActions;
|
|
37
37
|
|
|
38
38
|
return (
|
|
39
|
-
<header className="flex min-w-0 items-center justify-between gap-6 border-b border-
|
|
39
|
+
<header className="flex min-w-0 items-center justify-between gap-6 border-b border-dashboard-border-subtle pb-4 sm:pb-6 max-md:flex-col max-md:items-stretch">
|
|
40
40
|
<div className="min-w-0">
|
|
41
41
|
<h2 className="m-0 font-display text-3xl font-light leading-none tracking-[-0.03em] text-dashboard-text sm:text-4xl">
|
|
42
42
|
{props.title}
|
|
43
43
|
</h2>
|
|
44
|
-
<div className="mt-2 max-w-2xl font-
|
|
44
|
+
<div className="mt-2 max-w-2xl font-sans text-xs leading-relaxed text-dashboard-text-muted sm:text-sm">
|
|
45
45
|
{props.description}
|
|
46
46
|
</div>
|
|
47
47
|
</div>
|
|
@@ -27,31 +27,24 @@ export function SecondaryNavigation(props: {
|
|
|
27
27
|
}) {
|
|
28
28
|
const menuLinkClass = ({ isActive }: { isActive: boolean }) =>
|
|
29
29
|
cn(
|
|
30
|
-
"rounded-lg px-3 py-3 pl-6 font-
|
|
30
|
+
"rounded-lg px-3 py-3 pl-6 font-sans text-sm font-medium no-underline transition-colors",
|
|
31
31
|
isActive
|
|
32
|
-
? "bg-
|
|
33
|
-
: cn("hover:bg-
|
|
32
|
+
? "bg-dashboard-accent/[0.1] text-dashboard-accent-text"
|
|
33
|
+
: cn("hover:bg-dashboard-fill-faint", dashboardInteractiveTextClass),
|
|
34
34
|
);
|
|
35
35
|
|
|
36
36
|
return (
|
|
37
37
|
<div className="min-w-0">
|
|
38
38
|
<SecondaryNavigationPortal
|
|
39
39
|
desktop={
|
|
40
|
-
<div className="
|
|
41
|
-
<
|
|
42
|
-
className={cn(
|
|
43
|
-
dashboardContainerClass,
|
|
44
|
-
"min-w-0 px-4 py-2 md:px-8",
|
|
45
|
-
)}
|
|
46
|
-
>
|
|
47
|
-
<SegmentedNav ariaLabel={props.ariaLabel} items={props.items} />
|
|
48
|
-
</div>
|
|
40
|
+
<div className={cn(dashboardContainerClass, "min-w-0 px-4 md:px-8")}>
|
|
41
|
+
<SegmentedNav ariaLabel={props.ariaLabel} items={props.items} />
|
|
49
42
|
</div>
|
|
50
43
|
}
|
|
51
44
|
mobile={
|
|
52
45
|
<nav
|
|
53
46
|
aria-label={props.ariaLabel}
|
|
54
|
-
className="mt-3 grid gap-1 border-t border-
|
|
47
|
+
className="mt-3 grid gap-1 border-t border-dashboard-border pt-3"
|
|
55
48
|
>
|
|
56
49
|
{props.items.map((item) => (
|
|
57
50
|
<SiblingPageLink
|
|
@@ -63,7 +56,7 @@ export function SecondaryNavigation(props: {
|
|
|
63
56
|
</nav>
|
|
64
57
|
}
|
|
65
58
|
/>
|
|
66
|
-
<div className="px-4 pt-
|
|
59
|
+
<div className="border-b border-dashboard-border px-4 pt-2 sm:px-8 md:hidden">
|
|
67
60
|
<SegmentedNav ariaLabel={props.ariaLabel} fill items={props.items} />
|
|
68
61
|
</div>
|
|
69
62
|
{props.children}
|
|
@@ -16,7 +16,7 @@ export function SectionIntro(props: {
|
|
|
16
16
|
{props.title}
|
|
17
17
|
</h2>
|
|
18
18
|
{props.description ? (
|
|
19
|
-
<p className="mt-1.5 mb-0 max-w-2xl font-
|
|
19
|
+
<p className="mt-1.5 mb-0 max-w-2xl font-sans text-xs leading-relaxed text-dashboard-text-muted">
|
|
20
20
|
{props.description}
|
|
21
21
|
</p>
|
|
22
22
|
) : null}
|
|
@@ -3,7 +3,7 @@ import type { ReactNode } from "react";
|
|
|
3
3
|
/** Render compact section titles that fit inside operational panels. */
|
|
4
4
|
export function SectionTitle(props: { children: ReactNode }) {
|
|
5
5
|
return (
|
|
6
|
-
<div className="min-w-0 break-words font-
|
|
6
|
+
<div className="min-w-0 break-words font-sans text-xs font-medium leading-tight text-dashboard-text-muted">
|
|
7
7
|
{props.children}
|
|
8
8
|
</div>
|
|
9
9
|
);
|
|
@@ -14,7 +14,7 @@ export function StatCard(props: {
|
|
|
14
14
|
return (
|
|
15
15
|
<Card className="relative p-4 sm:p-5">
|
|
16
16
|
<div className="flex items-start justify-between gap-4">
|
|
17
|
-
<div className="font-
|
|
17
|
+
<div className="font-sans text-xs font-medium text-dashboard-text-muted">
|
|
18
18
|
{props.label}
|
|
19
19
|
</div>
|
|
20
20
|
<Icon aria-hidden="true" className="text-amber-400/55" size={15} />
|
|
@@ -23,7 +23,7 @@ export function StatCard(props: {
|
|
|
23
23
|
{props.value}
|
|
24
24
|
</div>
|
|
25
25
|
{props.detail ? (
|
|
26
|
-
<div className="mt-2 font-
|
|
26
|
+
<div className="mt-2 font-sans text-xs leading-relaxed text-dashboard-text-muted">
|
|
27
27
|
{props.detail}
|
|
28
28
|
</div>
|
|
29
29
|
) : null}
|
|
@@ -102,7 +102,7 @@ function ArchivedNotice(props: {
|
|
|
102
102
|
>
|
|
103
103
|
{restore.error ? (
|
|
104
104
|
<div
|
|
105
|
-
className="border-t border-rose-300/25 bg-rose-400/[0.12] px-3 py-2 font-
|
|
105
|
+
className="border-t border-rose-300/25 bg-rose-400/[0.12] px-3 py-2 font-sans text-xs text-rose-50/85"
|
|
106
106
|
role="alert"
|
|
107
107
|
>
|
|
108
108
|
Could not restore the conversation.
|
|
@@ -49,7 +49,7 @@ export function ConversationBrief(props: {
|
|
|
49
49
|
<StatusChip tone={outcomeTones[content.outcome.status]}>
|
|
50
50
|
{displayLabel(content.outcome.status)}
|
|
51
51
|
</StatusChip>
|
|
52
|
-
<span className="
|
|
52
|
+
<span className="text-xs text-dashboard-text-muted">
|
|
53
53
|
Brief v{props.brief.version} · updated{" "}
|
|
54
54
|
{formatTime(props.brief.updatedAt, {
|
|
55
55
|
dateStyle: "medium",
|
|
@@ -101,14 +101,14 @@ export function ConversationBrief(props: {
|
|
|
101
101
|
key={`${link.kind}:${link.url}`}
|
|
102
102
|
>
|
|
103
103
|
<a
|
|
104
|
-
className="min-w-0 break-all font-medium text-
|
|
104
|
+
className="min-w-0 break-all font-medium text-dashboard-accent-text underline decoration-dashboard-accent/30 underline-offset-2 hover:text-dashboard-accent-text"
|
|
105
105
|
href={link.url}
|
|
106
106
|
rel="noopener noreferrer"
|
|
107
107
|
target="_blank"
|
|
108
108
|
>
|
|
109
109
|
{link.label}
|
|
110
110
|
</a>
|
|
111
|
-
<span className="
|
|
111
|
+
<span className="text-xs text-dashboard-text-muted">
|
|
112
112
|
{displayLabel(link.kind)}
|
|
113
113
|
</span>
|
|
114
114
|
{link.status ? (
|
|
@@ -172,7 +172,7 @@ function BriefDecisions(props: { decisions: BriefContent["decisions"] }) {
|
|
|
172
172
|
<span className="min-w-0">{decision.text}</span>
|
|
173
173
|
</div>
|
|
174
174
|
{decision.by ? (
|
|
175
|
-
<div className="mt-0.5
|
|
175
|
+
<div className="mt-0.5 text-xs text-dashboard-text-muted">
|
|
176
176
|
by · {decision.by}
|
|
177
177
|
</div>
|
|
178
178
|
) : null}
|
|
@@ -124,13 +124,16 @@ function ChildAgentRow(props: {
|
|
|
124
124
|
|
|
125
125
|
return (
|
|
126
126
|
<button
|
|
127
|
-
className="grid w-full min-w-0 cursor-pointer gap-1.5 rounded-lg border border-dashboard-border-subtle bg-dashboard-surface px-3 py-2.5 text-left text-inherit transition-colors duration-200 hover:border-dashboard-border-emphasis hover:bg-dashboard-surface-hover focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-dashboard-focus"
|
|
127
|
+
className="grid w-full min-w-0 cursor-pointer gap-1.5 rounded-lg border border-dashboard-border-subtle bg-dashboard-surface-panel px-3 py-2.5 text-left text-inherit transition-colors duration-200 hover:border-dashboard-border-emphasis hover:bg-dashboard-surface-hover focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-dashboard-focus"
|
|
128
128
|
onClick={() =>
|
|
129
129
|
props.onOpen({
|
|
130
130
|
conversationId: agent.conversationId,
|
|
131
131
|
...(agent.redacted
|
|
132
132
|
? undefined
|
|
133
|
-
: {
|
|
133
|
+
: {
|
|
134
|
+
...(agent.name ? { agentName: agent.name } : undefined),
|
|
135
|
+
label: agent.title ?? agent.name,
|
|
136
|
+
}),
|
|
134
137
|
status: agent.status,
|
|
135
138
|
})
|
|
136
139
|
}
|
|
@@ -143,7 +146,7 @@ function ChildAgentRow(props: {
|
|
|
143
146
|
Private subagent
|
|
144
147
|
</span>
|
|
145
148
|
) : (
|
|
146
|
-
<span className="min-w-0 truncate font-
|
|
149
|
+
<span className="min-w-0 truncate font-medium text-dashboard-text-muted">
|
|
147
150
|
{agent.name ?? "subagent"}
|
|
148
151
|
</span>
|
|
149
152
|
)}
|
|
@@ -185,7 +188,7 @@ function ChildAgentRow(props: {
|
|
|
185
188
|
</span>
|
|
186
189
|
) : null}
|
|
187
190
|
{stats.length > 0 ? (
|
|
188
|
-
<span className="block
|
|
191
|
+
<span className="block text-xs tabular-nums text-dashboard-text-muted">
|
|
189
192
|
{stats.join(" · ")}
|
|
190
193
|
</span>
|
|
191
194
|
) : null}
|
|
@@ -351,7 +351,7 @@ export const ConversationComposer = memo(function ConversationComposer(
|
|
|
351
351
|
{props.error || imageError ? (
|
|
352
352
|
<div
|
|
353
353
|
aria-live="polite"
|
|
354
|
-
className="min-w-0 font-
|
|
354
|
+
className="min-w-0 font-sans text-xs leading-relaxed text-rose-300"
|
|
355
355
|
>
|
|
356
356
|
{imageError ?? props.error}
|
|
357
357
|
</div>
|
|
@@ -361,10 +361,10 @@ export const ConversationComposer = memo(function ConversationComposer(
|
|
|
361
361
|
// Accessory chrome needs a full footer row. Side-by-side mobile is
|
|
362
362
|
// only for the bare reply dock.
|
|
363
363
|
props.footerStart
|
|
364
|
-
? "block overflow-hidden focus-within:border-
|
|
365
|
-
: "grid grid-cols-[minmax(0,1fr)_auto] items-end overflow-hidden focus-within:border-
|
|
364
|
+
? "block overflow-hidden focus-within:border-dashboard-focus/45 focus-within:ring-1 focus-within:ring-dashboard-focus/25"
|
|
365
|
+
: "grid grid-cols-[minmax(0,1fr)_auto] items-end overflow-hidden focus-within:border-dashboard-accent/35 focus-within:ring-1 focus-within:ring-dashboard-focus/35 md:block",
|
|
366
366
|
dashboardComposerSurfaceClass,
|
|
367
|
-
dragging && "ring-2 ring-
|
|
367
|
+
dragging && "ring-2 ring-dashboard-focus",
|
|
368
368
|
)}
|
|
369
369
|
onDragOver={(event) => {
|
|
370
370
|
if (!event.dataTransfer.types.includes("Files")) return;
|
|
@@ -431,7 +431,7 @@ export const ConversationComposer = memo(function ConversationComposer(
|
|
|
431
431
|
autoCapitalize="off"
|
|
432
432
|
autoComplete="off"
|
|
433
433
|
autoCorrect="off"
|
|
434
|
-
className="min-h-12 max-h-28 w-full resize-none overflow-y-auto border-0 bg-transparent px-3 py-3 font-sans text-base leading-relaxed text-dashboard-text outline-none placeholder:text-dashboard-text-muted/65 md:min-h-14 md:max-h-none md:
|
|
434
|
+
className="min-h-12 max-h-28 w-full resize-none overflow-y-auto border-0 bg-transparent px-3 py-3 font-sans text-base leading-relaxed text-dashboard-text outline-none placeholder:text-dashboard-text-muted/65 md:min-h-14 md:max-h-none md:overflow-visible md:px-4 md:py-3"
|
|
435
435
|
disabled={Boolean(props.restoreDraftOnError && createPending)}
|
|
436
436
|
enterKeyHint="send"
|
|
437
437
|
id={id}
|
|
@@ -462,6 +462,7 @@ export const ConversationComposer = memo(function ConversationComposer(
|
|
|
462
462
|
aria-label="Attach images"
|
|
463
463
|
disabled={sendLocked || readingImages}
|
|
464
464
|
onClick={() => fileInputRef.current?.click()}
|
|
465
|
+
size="icon"
|
|
465
466
|
title="Attach images (up to 3 MB total)"
|
|
466
467
|
type="button"
|
|
467
468
|
>
|
|
@@ -478,7 +479,6 @@ export const ConversationComposer = memo(function ConversationComposer(
|
|
|
478
479
|
{props.onStop ? (
|
|
479
480
|
<Button
|
|
480
481
|
aria-label={props.stopPending ? "Stopping" : "Stop"}
|
|
481
|
-
className="rounded-lg font-sans"
|
|
482
482
|
disabled={props.stopPending || !online}
|
|
483
483
|
onClick={() => void stopTurn()}
|
|
484
484
|
title="Stop Junior"
|
|
@@ -491,7 +491,7 @@ export const ConversationComposer = memo(function ConversationComposer(
|
|
|
491
491
|
) : null}
|
|
492
492
|
<Button
|
|
493
493
|
aria-label={sendLocked ? "Sending message" : props.submitLabel}
|
|
494
|
-
className="
|
|
494
|
+
className="disabled:!border-transparent disabled:!bg-dashboard-fill-hover disabled:!text-dashboard-text-muted disabled:!opacity-100"
|
|
495
495
|
disabled={
|
|
496
496
|
(!canSend && !images.length) ||
|
|
497
497
|
!online ||
|
|
@@ -499,6 +499,7 @@ export const ConversationComposer = memo(function ConversationComposer(
|
|
|
499
499
|
readingImages
|
|
500
500
|
}
|
|
501
501
|
title={sendLocked ? "Sending message" : props.submitLabel}
|
|
502
|
+
tone="primary"
|
|
502
503
|
type="submit"
|
|
503
504
|
>
|
|
504
505
|
<Send aria-hidden="true" size={14} />
|
|
@@ -114,7 +114,7 @@ export function ConversationHeader(props: {
|
|
|
114
114
|
<Ellipsis aria-hidden="true" size={18} strokeWidth={2} />
|
|
115
115
|
</HeaderIconButton>
|
|
116
116
|
{mobileMenuOpen ? (
|
|
117
|
-
<div className="absolute right-0 top-[calc(100%+0.35rem)] z-40 w-56 rounded-xl border border-
|
|
117
|
+
<div className="absolute right-0 top-[calc(100%+0.35rem)] z-40 w-56 rounded-xl border border-dashboard-border-strong bg-dashboard-surface-raised/95 p-1.5 shadow-2xl shadow-black/75 backdrop-blur-xl">
|
|
118
118
|
<ConversationHeaderActions
|
|
119
119
|
archive={props.archive}
|
|
120
120
|
conversationId={props.conversationId}
|
|
@@ -138,7 +138,7 @@ export function ConversationHeader(props: {
|
|
|
138
138
|
/>
|
|
139
139
|
{openMobileNavigation ? (
|
|
140
140
|
<button
|
|
141
|
-
className="mt-0.5 flex w-full cursor-pointer items-center gap-2.5 rounded-md border-0 bg-transparent px-2.5 py-2 text-left text-sm font-semibold text-dashboard-text transition-colors hover:bg-
|
|
141
|
+
className="mt-0.5 flex w-full cursor-pointer items-center gap-2.5 rounded-md border-0 bg-transparent px-2.5 py-2 text-left text-sm font-semibold text-dashboard-text transition-colors hover:bg-dashboard-fill-hover focus-visible:bg-dashboard-fill-hover focus-visible:outline-none"
|
|
142
142
|
onClick={() => {
|
|
143
143
|
setMobileMenuOpen(false);
|
|
144
144
|
openMobileNavigation();
|
|
@@ -175,7 +175,7 @@ export function ConversationHeader(props: {
|
|
|
175
175
|
<MobileHeaderLivePortal>{liveIndicator}</MobileHeaderLivePortal>
|
|
176
176
|
<header
|
|
177
177
|
className={cn(
|
|
178
|
-
"sticky top-0 z-10 -mx-4 border-b border-dashboard-border
|
|
178
|
+
"sticky top-0 z-10 -mx-4 border-b border-dashboard-border bg-dashboard-bg md:-mx-7",
|
|
179
179
|
!showMobileHeader && "hidden md:block",
|
|
180
180
|
)}
|
|
181
181
|
>
|
|
@@ -221,12 +221,12 @@ export function ConversationHeader(props: {
|
|
|
221
221
|
{props.linkedWork ? (
|
|
222
222
|
<div
|
|
223
223
|
aria-label="Linked work"
|
|
224
|
-
className="border-t border-dashboard-border
|
|
224
|
+
className="border-t border-dashboard-border-subtle px-4 py-2.5 md:px-7"
|
|
225
225
|
>
|
|
226
226
|
{props.linkedWork}
|
|
227
227
|
</div>
|
|
228
228
|
) : null}
|
|
229
|
-
<div className="hidden border-t border-dashboard-border px-7 md:flex">
|
|
229
|
+
<div className="hidden border-t border-dashboard-border-subtle px-7 md:flex">
|
|
230
230
|
<TranscriptViewToggle
|
|
231
231
|
labelled
|
|
232
232
|
onChange={props.onViewChange}
|
|
@@ -96,7 +96,7 @@ export function ConversationHeaderActions(props: {
|
|
|
96
96
|
<Button
|
|
97
97
|
aria-label="Conversation details"
|
|
98
98
|
aria-pressed={props.detailsOpen}
|
|
99
|
-
className="ml-2
|
|
99
|
+
className="ml-2"
|
|
100
100
|
onClick={props.onDetailsClick}
|
|
101
101
|
>
|
|
102
102
|
<PanelRight aria-hidden="true" size={15} strokeWidth={2} />
|
|
@@ -153,13 +153,13 @@ function ViewModeButton(props: {
|
|
|
153
153
|
<ToggleButton
|
|
154
154
|
aria-label={props.label}
|
|
155
155
|
className={cn(
|
|
156
|
-
"!
|
|
156
|
+
"!no-underline",
|
|
157
157
|
props.labelled
|
|
158
|
-
? "relative flex h-11 items-center gap-2 px-0 py-0 text-
|
|
159
|
-
: "grid size-7 place-items-center rounded px-0 py-0",
|
|
158
|
+
? "relative flex h-11 items-center gap-2 rounded-none px-0 py-0 text-sm after:absolute after:inset-x-0 after:bottom-0 after:h-0.5"
|
|
159
|
+
: "grid size-7 place-items-center rounded-md px-0 py-0",
|
|
160
160
|
props.active &&
|
|
161
161
|
(props.labelled
|
|
162
|
-
? "text-
|
|
162
|
+
? "text-dashboard-text after:bg-dashboard-text-solid"
|
|
163
163
|
: "bg-dashboard-fill-hover text-dashboard-text"),
|
|
164
164
|
)}
|
|
165
165
|
onClick={props.onClick}
|
|
@@ -191,7 +191,7 @@ export function HeaderIconButton(props: {
|
|
|
191
191
|
aria-pressed={props.pressed}
|
|
192
192
|
className={cn(
|
|
193
193
|
"text-dashboard-text-muted",
|
|
194
|
-
props.pressed && "bg-
|
|
194
|
+
props.pressed && "bg-dashboard-fill-strong text-dashboard-text",
|
|
195
195
|
)}
|
|
196
196
|
onClick={props.onClick}
|
|
197
197
|
size="icon"
|
|
@@ -233,8 +233,8 @@ function MenuActionButton(props: {
|
|
|
233
233
|
aria-label={props.label}
|
|
234
234
|
aria-pressed={props.pressed}
|
|
235
235
|
className={cn(
|
|
236
|
-
"flex w-full cursor-pointer items-center gap-2.5 rounded-md border-0 bg-transparent px-2.5 py-2 text-left text-sm font-semibold text-dashboard-text transition-colors hover:bg-
|
|
237
|
-
props.pressed && "bg-
|
|
236
|
+
"flex w-full cursor-pointer items-center gap-2.5 rounded-md border-0 bg-transparent px-2.5 py-2 text-left text-sm font-semibold text-dashboard-text transition-colors hover:bg-dashboard-fill-strong focus-visible:bg-dashboard-fill-strong focus-visible:outline-none",
|
|
237
|
+
props.pressed && "bg-dashboard-fill-strong",
|
|
238
238
|
)}
|
|
239
239
|
onClick={props.onClick}
|
|
240
240
|
type="button"
|
|
@@ -258,7 +258,7 @@ function ArchiveConversationButton(
|
|
|
258
258
|
return (
|
|
259
259
|
<button
|
|
260
260
|
aria-label={label}
|
|
261
|
-
className="flex w-full cursor-pointer items-center gap-2.5 rounded-md border-0 bg-transparent px-2.5 py-2 text-left text-sm font-semibold text-dashboard-text transition-colors hover:bg-
|
|
261
|
+
className="flex w-full cursor-pointer items-center gap-2.5 rounded-md border-0 bg-transparent px-2.5 py-2 text-left text-sm font-semibold text-dashboard-text transition-colors hover:bg-dashboard-fill-strong focus-visible:bg-dashboard-fill-strong focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
|
|
262
262
|
disabled={props.disabled}
|
|
263
263
|
onClick={props.onClick}
|
|
264
264
|
type="button"
|
|
@@ -172,7 +172,7 @@ function ConversationCardSection(props: {
|
|
|
172
172
|
return (
|
|
173
173
|
<section aria-labelledby={`conversation-section-${props.section.key}`}>
|
|
174
174
|
<h3
|
|
175
|
-
className="mb-2 mt-0 px-1 font-
|
|
175
|
+
className="mb-2 mt-0 px-1 font-sans text-xs font-medium text-dashboard-text-muted"
|
|
176
176
|
id={`conversation-section-${props.section.key}`}
|
|
177
177
|
>
|
|
178
178
|
{props.section.label}
|
|
@@ -238,7 +238,7 @@ function ConversationCard(props: {
|
|
|
238
238
|
</div>
|
|
239
239
|
<div className="flex items-start gap-3">
|
|
240
240
|
<Link
|
|
241
|
-
className="pointer-events-auto whitespace-nowrap font-
|
|
241
|
+
className="pointer-events-auto whitespace-nowrap font-sans text-xs tabular-nums text-dashboard-text-muted hover:text-dashboard-text focus:outline-none focus:ring-2 focus:ring-dashboard-focus"
|
|
242
242
|
to={conversationPath(conversation.id)}
|
|
243
243
|
>
|
|
244
244
|
{formatRelativeTime(conversation.lastSeenAt)}
|
|
@@ -272,7 +272,7 @@ function ConversationCard(props: {
|
|
|
272
272
|
{status === "active" ? "Working…" : "No recent message"}
|
|
273
273
|
</p>
|
|
274
274
|
)}
|
|
275
|
-
<div className="relative z-[1] flex min-w-0 flex-wrap items-center gap-x-1.5 gap-y-1 font-
|
|
275
|
+
<div className="relative z-[1] flex min-w-0 flex-wrap items-center gap-x-1.5 gap-y-1 font-sans text-xs text-dashboard-text-muted pointer-events-none">
|
|
276
276
|
{location ? <span className="truncate">{location}</span> : null}
|
|
277
277
|
{location && participants.length > 0 ? (
|
|
278
278
|
<span aria-hidden="true">·</span>
|
|
@@ -45,7 +45,7 @@ export function ConversationListStatusIcon(props: {
|
|
|
45
45
|
className={cn(
|
|
46
46
|
"size-1.5 shrink-0 rounded-full",
|
|
47
47
|
props.status === "failed" && "bg-rose-300",
|
|
48
|
-
props.status === "idle" && "bg-
|
|
48
|
+
props.status === "idle" && "bg-dashboard-text-faint",
|
|
49
49
|
)}
|
|
50
50
|
/>
|
|
51
51
|
);
|
|
@@ -66,17 +66,17 @@ export function ConversationMemories(props: { conversationId: string }) {
|
|
|
66
66
|
<ol className="m-0 grid list-none gap-3 p-0">
|
|
67
67
|
{query.data.memories.map((memory) => (
|
|
68
68
|
<li
|
|
69
|
-
className="grid gap-2 rounded-lg border border-dashboard-border-subtle bg-dashboard-surface px-3 py-3"
|
|
69
|
+
className="grid gap-2 rounded-lg border border-dashboard-border-subtle bg-dashboard-surface-panel px-3 py-3"
|
|
70
70
|
key={memory.id}
|
|
71
71
|
>
|
|
72
72
|
<p className="m-0 whitespace-pre-wrap break-words text-sm leading-relaxed text-dashboard-text">
|
|
73
73
|
{memory.content}
|
|
74
74
|
</p>
|
|
75
|
-
<div className="flex flex-wrap items-center gap-1.5
|
|
76
|
-
<span className="rounded border border-dashboard-border-subtle bg-dashboard-surface-raised px-1.5 py-0.5">
|
|
75
|
+
<div className="flex flex-wrap items-center gap-1.5 text-xs tabular-nums text-dashboard-text-muted">
|
|
76
|
+
<span className="rounded-md border border-dashboard-border-subtle bg-dashboard-surface-raised px-1.5 py-0.5">
|
|
77
77
|
{memory.kind}
|
|
78
78
|
</span>
|
|
79
|
-
<span className="rounded border border-dashboard-border-subtle bg-dashboard-surface-raised px-1.5 py-0.5">
|
|
79
|
+
<span className="rounded-md border border-dashboard-border-subtle bg-dashboard-surface-raised px-1.5 py-0.5">
|
|
80
80
|
{memory.visibility}
|
|
81
81
|
</span>
|
|
82
82
|
<time className="ml-auto" dateTime={memory.capturedAt}>
|