@sentry/junior-dashboard 0.248.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.
Files changed (136) hide show
  1. package/dist/app.js +2 -2
  2. package/dist/client.js +36 -35
  3. package/dist/index.js +2 -2
  4. package/dist/tailwind.css +1 -1
  5. package/package.json +3 -3
  6. package/src/client/App.tsx +1 -5
  7. package/src/client/components/ActorAvatar.tsx +7 -4
  8. package/src/client/components/AutomationCard.tsx +2 -2
  9. package/src/client/components/Button.tsx +12 -11
  10. package/src/client/components/ConversationList.tsx +3 -3
  11. package/src/client/components/ConversationSummary.tsx +2 -1
  12. package/src/client/components/DetailList.tsx +3 -3
  13. package/src/client/components/Drawer.tsx +2 -2
  14. package/src/client/components/EmptyTelemetry.tsx +1 -1
  15. package/src/client/components/Field.tsx +1 -2
  16. package/src/client/components/FilterBar.tsx +6 -6
  17. package/src/client/components/Metric.tsx +4 -4
  18. package/src/client/components/Notice.tsx +7 -7
  19. package/src/client/components/PageContentSkeleton.tsx +2 -2
  20. package/src/client/components/Pagination.tsx +2 -2
  21. package/src/client/components/ParticipantAvatarStack.tsx +4 -4
  22. package/src/client/components/ProfileMenu.tsx +5 -7
  23. package/src/client/components/README.md +122 -58
  24. package/src/client/components/SearchInput.tsx +4 -3
  25. package/src/client/components/SegmentedNav.tsx +10 -17
  26. package/src/client/components/SegmentedTabs.tsx +3 -3
  27. package/src/client/components/Select.tsx +1 -1
  28. package/src/client/components/SelectableRow.tsx +2 -2
  29. package/src/client/components/Skeleton.tsx +1 -1
  30. package/src/client/components/StatusChip.tsx +1 -1
  31. package/src/client/components/StatusDot.tsx +1 -1
  32. package/src/client/components/TextInput.tsx +1 -1
  33. package/src/client/components/Tooltip.tsx +2 -2
  34. package/src/client/components/VersionDriftBanner.tsx +2 -2
  35. package/src/client/components/charts/ActivityChart.tsx +5 -6
  36. package/src/client/components/charts/CacheWrites.tsx +3 -3
  37. package/src/client/components/charts/ChartHeader.tsx +4 -4
  38. package/src/client/components/charts/ChartLegend.tsx +1 -1
  39. package/src/client/components/charts/InputCacheChart.tsx +5 -5
  40. package/src/client/components/charts/WorkspaceUsageChart.tsx +4 -11
  41. package/src/client/components/controls/DirectorySortSelect.tsx +2 -2
  42. package/src/client/components/directory/DirectoryMetric.tsx +2 -2
  43. package/src/client/components/directory/DirectoryRowsSkeleton.tsx +5 -5
  44. package/src/client/components/directory/DirectoryTable.tsx +3 -3
  45. package/src/client/components/layout/CardHeader.tsx +4 -4
  46. package/src/client/components/layout/DashboardChrome.tsx +9 -3
  47. package/src/client/components/layout/DashboardHeader.tsx +7 -7
  48. package/src/client/components/layout/PageHeader.tsx +2 -2
  49. package/src/client/components/layout/SecondaryNavigation.tsx +7 -14
  50. package/src/client/components/layout/SectionIntro.tsx +1 -1
  51. package/src/client/components/layout/SectionTitle.tsx +1 -1
  52. package/src/client/components/metrics/StatCard.tsx +2 -2
  53. package/src/client/conversations/ConversationArchiveNotices.tsx +1 -1
  54. package/src/client/conversations/ConversationBrief.tsx +4 -4
  55. package/src/client/conversations/ConversationChildAgents.tsx +7 -4
  56. package/src/client/conversations/ConversationComposer.tsx +8 -7
  57. package/src/client/conversations/ConversationHeader.tsx +5 -5
  58. package/src/client/conversations/ConversationHeaderActions.tsx +9 -9
  59. package/src/client/conversations/ConversationHomeList.tsx +3 -3
  60. package/src/client/conversations/ConversationListStatusIcon.tsx +1 -1
  61. package/src/client/conversations/ConversationMemories.tsx +4 -4
  62. package/src/client/conversations/ConversationMeta.tsx +10 -10
  63. package/src/client/conversations/ConversationPage.tsx +2 -1
  64. package/src/client/conversations/ConversationSidebar.tsx +6 -6
  65. package/src/client/conversations/ConversationUsageBreakdown.tsx +4 -4
  66. package/src/client/conversations/ConversationWorkspace.tsx +1 -1
  67. package/src/client/conversations/ConversationWorkspaceLoading.tsx +4 -4
  68. package/src/client/conversations/CopyMarkdownButton.tsx +1 -1
  69. package/src/client/conversations/EventUsage.tsx +2 -2
  70. package/src/client/conversations/PendingMailboxStack.tsx +5 -5
  71. package/src/client/conversations/README.md +9 -0
  72. package/src/client/conversations/SubagentTranscriptDrawer.tsx +39 -23
  73. package/src/client/conversations/ToolFrame.tsx +36 -14
  74. package/src/client/conversations/TranscriptActivityGroup.tsx +10 -3
  75. package/src/client/conversations/TranscriptAttachmentsDeliveredView.tsx +4 -6
  76. package/src/client/conversations/TranscriptContextEventView.tsx +2 -2
  77. package/src/client/conversations/TranscriptEventView.tsx +1 -1
  78. package/src/client/conversations/TranscriptMarkdown.tsx +3 -3
  79. package/src/client/conversations/TranscriptMessageContextView.tsx +7 -7
  80. package/src/client/conversations/TranscriptMessageView.tsx +2 -6
  81. package/src/client/conversations/TranscriptRailEvent.tsx +20 -8
  82. package/src/client/conversations/TranscriptReasoningView.tsx +12 -12
  83. package/src/client/conversations/TranscriptStructuredEventView.tsx +16 -11
  84. package/src/client/conversations/TranscriptSubagentView.tsx +64 -39
  85. package/src/client/conversations/TranscriptText.tsx +5 -4
  86. package/src/client/conversations/TranscriptToolView.tsx +9 -11
  87. package/src/client/conversations/TranscriptTurnContextView.tsx +3 -3
  88. package/src/client/conversations/TranscriptView.tsx +3 -3
  89. package/src/client/conversations/UsageCard.tsx +1 -1
  90. package/src/client/conversations/eventTranscript.ts +7 -0
  91. package/src/client/conversations/transcriptMarkdownLinks.ts +2 -4
  92. package/src/client/conversations/transcriptStyles.ts +1 -1
  93. package/src/client/pages/PersonalTokensPage.tsx +4 -4
  94. package/src/client/pages/admin/AdminPage.tsx +2 -2
  95. package/src/client/pages/automations/AutomationCostChart.tsx +2 -2
  96. package/src/client/pages/automations/AutomationDetailsDrawer.tsx +5 -10
  97. package/src/client/pages/automations/AutomationEditor.tsx +1 -1
  98. package/src/client/pages/automations/AutomationExecutionChart.tsx +2 -2
  99. package/src/client/pages/automations/AutomationExecutionStatusChart.tsx +2 -2
  100. package/src/client/pages/automations/AutomationExecutionsPage.tsx +4 -4
  101. package/src/client/pages/automations/AutomationRow.tsx +4 -4
  102. package/src/client/pages/automations/AutomationRunsPage.tsx +3 -3
  103. package/src/client/pages/automations/AutomationScheduleFields.tsx +1 -1
  104. package/src/client/pages/automations/AutomationVersionsPage.tsx +1 -1
  105. package/src/client/pages/code/CodeActivityChart.tsx +7 -6
  106. package/src/client/pages/code/CodeChangeRow.tsx +1 -1
  107. package/src/client/pages/code/CodePage.tsx +5 -5
  108. package/src/client/pages/code/RepositoryPage.tsx +2 -2
  109. package/src/client/pages/dev/ComponentsPage.tsx +40 -146
  110. package/src/client/pages/dev/TranscriptActivityFixtures.tsx +206 -0
  111. package/src/client/pages/locations/LocationDetailPage.tsx +4 -4
  112. package/src/client/pages/locations/LocationDirectory.tsx +1 -1
  113. package/src/client/pages/locations/PrivateActivityCard.tsx +3 -3
  114. package/src/client/pages/memory/MemoryCostChart.tsx +3 -5
  115. package/src/client/pages/memory/MemoryDetailsDrawer.tsx +5 -5
  116. package/src/client/pages/memory/MemoryPage.tsx +15 -15
  117. package/src/client/pages/memory/MemoryTimeline.tsx +3 -5
  118. package/src/client/pages/people/ContributionGrid.tsx +8 -5
  119. package/src/client/pages/people/PersonProfilePage.tsx +3 -6
  120. package/src/client/pages/people/ProfilePluginReports.tsx +2 -2
  121. package/src/client/pages/system/GuardianActivity.tsx +9 -9
  122. package/src/client/pages/system/PluginBarChart.tsx +4 -6
  123. package/src/client/pages/system/PluginDetails.tsx +11 -7
  124. package/src/client/pages/system/PluginPanels.tsx +8 -8
  125. package/src/client/pages/system/PluginReportRecordSet.tsx +14 -14
  126. package/src/client/pages/system/PluginReports.tsx +7 -11
  127. package/src/client/pages/system/SkillInventory.tsx +9 -9
  128. package/src/client/pages/system/SystemActivity.tsx +1 -1
  129. package/src/client/pages/system/SystemPage.tsx +3 -6
  130. package/src/client/pages/system/WorkspaceDetails.tsx +2 -5
  131. package/src/client/pages/system/WorkspaceEditor.tsx +2 -2
  132. package/src/client/pages/system/WorkspaceList.tsx +2 -2
  133. package/src/client/pages/user/PluginUserPage.tsx +3 -3
  134. package/src/client/styles.ts +5 -4
  135. package/src/client/types.ts +2 -0
  136. package/src/tailwind.css +36 -38
@@ -315,7 +315,7 @@ function MemoryListHeader() {
315
315
  return (
316
316
  <div
317
317
  className={cn(
318
- "hidden items-center gap-3 border-b border-white/[0.07] px-4 py-2.5 text-left font-mono text-xs uppercase tracking-[0.12em] text-dashboard-text-muted sm:grid",
318
+ "hidden items-center gap-3 border-b border-dashboard-border px-4 py-2.5 text-left font-sans font-medium text-xs text-dashboard-text-muted sm:grid",
319
319
  MEMORY_GRID,
320
320
  )}
321
321
  role="row"
@@ -344,7 +344,7 @@ function MemorySummary(props: { data: MemoryDashboardData }) {
344
344
  {
345
345
  detail: "workspace shareable",
346
346
  label: "Public",
347
- tone: "text-cyan-100",
347
+ tone: "text-dashboard-accent-text",
348
348
  value: stats.public.toLocaleString("en-US"),
349
349
  },
350
350
  {
@@ -356,11 +356,11 @@ function MemorySummary(props: { data: MemoryDashboardData }) {
356
356
  return (
357
357
  <section
358
358
  aria-label="Memory summary"
359
- className="grid grid-cols-2 gap-px border-y border-white/[0.06] bg-white/[0.06] lg:grid-cols-4"
359
+ className="grid grid-cols-2 gap-px border-y border-dashboard-border-subtle bg-dashboard-fill-hover lg:grid-cols-4"
360
360
  >
361
361
  {items.map((item) => (
362
- <div className="bg-[#050507] px-4 py-4 sm:px-5" key={item.label}>
363
- <div className="font-mono text-xs uppercase tracking-[0.12em] text-dashboard-text-muted">
362
+ <div className="bg-dashboard-bg px-4 py-4 sm:px-5" key={item.label}>
363
+ <div className="font-sans font-medium text-xs text-dashboard-text-muted">
364
364
  {item.label}
365
365
  </div>
366
366
  <div
@@ -371,7 +371,7 @@ function MemorySummary(props: { data: MemoryDashboardData }) {
371
371
  >
372
372
  {item.value}
373
373
  </div>
374
- <div className="mt-1 font-mono text-xs leading-relaxed text-dashboard-text-muted">
374
+ <div className="mt-1 font-sans text-xs leading-relaxed text-dashboard-text-muted">
375
375
  {item.detail}
376
376
  </div>
377
377
  </div>
@@ -387,10 +387,10 @@ function MemoryKindPanel(props: { data: MemoryDashboardData }) {
387
387
  <h2 className="m-0 font-display text-xl font-medium text-dashboard-text">
388
388
  What Junior remembers
389
389
  </h2>
390
- <p className="mt-1 mb-0 font-mono text-xs leading-relaxed text-dashboard-text-muted">
390
+ <p className="mt-1 mb-0 font-sans text-xs leading-relaxed text-dashboard-text-muted">
391
391
  Across personal and public scopes.
392
392
  </p>
393
- <div className="mt-5 grid gap-px overflow-hidden rounded border border-white/[0.06] bg-white/[0.055]">
393
+ <div className="mt-5 grid gap-px overflow-hidden rounded-md border border-dashboard-border-subtle bg-dashboard-fill-hover">
394
394
  <OverviewBreakdownRow
395
395
  detail="Almost entirely personal"
396
396
  icon={UserRound}
@@ -422,10 +422,10 @@ function MemoryOriginPanel(props: { data: MemoryDashboardData }) {
422
422
  <h2 className="m-0 font-display text-xl font-medium text-dashboard-text">
423
423
  How they got here
424
424
  </h2>
425
- <p className="mt-1 mb-0 font-mono text-xs leading-relaxed text-dashboard-text-muted">
425
+ <p className="mt-1 mb-0 font-sans text-xs leading-relaxed text-dashboard-text-muted">
426
426
  Same totals, split by how they were written.
427
427
  </p>
428
- <div className="mt-5 grid gap-px overflow-hidden rounded border border-white/[0.06] bg-white/[0.055]">
428
+ <div className="mt-5 grid gap-px overflow-hidden rounded-md border border-dashboard-border-subtle bg-dashboard-fill-hover">
429
429
  <OverviewBreakdownRow
430
430
  detail="Passive extraction after runs"
431
431
  icon={Sparkles}
@@ -457,15 +457,15 @@ function OverviewBreakdownRow(props: {
457
457
  }) {
458
458
  const Icon = props.icon;
459
459
  return (
460
- <div className="flex items-center gap-3 bg-[#09090b] px-3 py-3">
461
- <div className="grid size-9 shrink-0 place-items-center rounded border border-white/[0.07] bg-white/[0.025] text-dashboard-text-muted">
460
+ <div className="flex items-center gap-3 bg-dashboard-bg-elevated px-3 py-3">
461
+ <div className="grid size-9 shrink-0 place-items-center rounded-md border border-dashboard-border bg-dashboard-fill-soft text-dashboard-text-muted">
462
462
  <Icon aria-hidden="true" size={15} />
463
463
  </div>
464
464
  <div className="min-w-0 flex-1">
465
465
  <div className="font-display text-base font-medium text-dashboard-text">
466
466
  {props.label}
467
467
  </div>
468
- <div className="mt-0.5 font-mono text-xs leading-relaxed text-dashboard-text-muted">
468
+ <div className="mt-0.5 font-sans text-xs leading-relaxed text-dashboard-text-muted">
469
469
  {props.detail}
470
470
  </div>
471
471
  </div>
@@ -492,7 +492,7 @@ function MemoryRow(props: {
492
492
  <SelectableRow
493
493
  className={cn(
494
494
  "flex items-stretch",
495
- !props.first && "border-t border-white/[0.055]",
495
+ !props.first && "border-t border-dashboard-border-subtle",
496
496
  )}
497
497
  onSelect={props.onSelect}
498
498
  selected={props.selected}
@@ -521,7 +521,7 @@ function MemoryRow(props: {
521
521
  />
522
522
  </h3>
523
523
  </div>
524
- <div className="mt-1.5 truncate font-mono text-xs leading-relaxed text-dashboard-text-muted">
524
+ <div className="mt-1.5 truncate font-sans text-xs leading-relaxed text-dashboard-text-muted">
525
525
  Source: {source}
526
526
  <span className="sm:hidden">
527
527
  {" "}
@@ -43,7 +43,7 @@ export function MemoryTimeline(props: {
43
43
  <h2 className="m-0 font-display text-xl font-medium text-dashboard-text">
44
44
  Activity over time
45
45
  </h2>
46
- <p className="mt-1 mb-0 font-mono text-xs leading-relaxed text-dashboard-text-muted">
46
+ <p className="mt-1 mb-0 font-sans text-xs leading-relaxed text-dashboard-text-muted">
47
47
  {bucketUnit === "hour"
48
48
  ? "Stacked personal + public memories created each hour."
49
49
  : bucketUnit === "6hour"
@@ -80,9 +80,7 @@ export function MemoryTimeline(props: {
80
80
  date={day.date}
81
81
  summary={`${day.personal} personal, ${day.public} public, ${total} total memories`}
82
82
  >
83
- <g
84
- tabIndex={0}
85
- >
83
+ <g tabIndex={0}>
86
84
  {series.map((item) => {
87
85
  const value = day[item.key];
88
86
  const segmentHeight = (value / maximum) * layout.plotHeight;
@@ -118,7 +116,7 @@ export function MemoryTimeline(props: {
118
116
  />
119
117
  </ChartSvg>
120
118
  {!hasMemories ? (
121
- <div className="pointer-events-none absolute inset-0 grid place-items-center pt-12 font-mono text-xs text-dashboard-text-muted">
119
+ <div className="pointer-events-none absolute inset-0 grid place-items-center pt-12 font-sans text-xs text-dashboard-text-muted">
122
120
  No memories were learned in this period.
123
121
  </div>
124
122
  ) : null}
@@ -85,7 +85,10 @@ export function ContributionGrid(props: { days: ContributionDay[] }) {
85
85
  rows={[
86
86
  ["conversations", day.conversations],
87
87
  ["runtime", activityRuntime(day)],
88
- ["spend", formatCostSummary({ total: day.costUsd ?? 0 })],
88
+ [
89
+ "spend",
90
+ formatCostSummary({ total: day.costUsd ?? 0 }),
91
+ ],
89
92
  ["tokens", formatCompactNumber(day.tokens ?? 0)],
90
93
  ]}
91
94
  />
@@ -96,7 +99,7 @@ export function ContributionGrid(props: { days: ContributionDay[] }) {
96
99
  <span
97
100
  aria-label={`${day.date}: ${day.conversations} conversations, ${activityRuntime(day)}, ${formatCostSummary({ total: day.costUsd ?? 0 })} spend, ${formatCompactNumber(day.tokens ?? 0)} tokens`}
98
101
  className={cn(
99
- "size-3 border border-black/40 outline-none focus-visible:ring-2 focus-visible:ring-[#beaaff]",
102
+ "size-3 border border-dashboard-overlay outline-none focus-visible:ring-2 focus-visible:ring-dashboard-focus",
100
103
  activityClass(day.conversations, max),
101
104
  )}
102
105
  role="listitem"
@@ -106,20 +109,20 @@ export function ContributionGrid(props: { days: ContributionDay[] }) {
106
109
  ) : (
107
110
  <span
108
111
  aria-hidden="true"
109
- className="size-3 border border-black/40 bg-[#101010]"
112
+ className="size-3 border border-dashboard-overlay bg-dashboard-surface-raised"
110
113
  key={`empty-${weekIndex}-${dayIndex}`}
111
114
  />
112
115
  ),
113
116
  ),
114
117
  )}
115
118
  </div>
116
- <div className="mt-3 flex items-center gap-1 text-xs font-semibold uppercase leading-none text-dashboard-text-muted">
119
+ <div className="mt-3 flex items-center gap-1 text-xs font-semibold leading-none text-dashboard-text-muted">
117
120
  <span>Less</span>
118
121
  {[0, 1, 2, 3, 4].map((level) => (
119
122
  <span
120
123
  aria-hidden="true"
121
124
  className={cn(
122
- "size-3 border border-black/40",
125
+ "size-3 border border-dashboard-overlay",
123
126
  level === 0 && "bg-dashboard-surface-hover",
124
127
  level === 1 && "bg-[#133225]",
125
128
  level === 2 && "bg-[#176a4a]",
@@ -112,10 +112,7 @@ export function Profile(props: {
112
112
  />
113
113
 
114
114
  <section className="grid gap-4" aria-labelledby="profile-metrics-title">
115
- <SectionIntro
116
- id="profile-metrics-title"
117
- title="Usage over time"
118
- />
115
+ <SectionIntro id="profile-metrics-title" title="Usage over time" />
119
116
  <SystemMetricCharts
120
117
  bucketUnit={timeRangeBucketUnit(range)}
121
118
  days={selectTimeSeries({
@@ -184,7 +181,7 @@ export function Profile(props: {
184
181
  <Card as="section" className="mb-0" variant="section">
185
182
  <SectionHeader
186
183
  actions={
187
- <div className="font-mono text-xs uppercase tracking-[0.12em] text-dashboard-text-muted">
184
+ <div className="font-sans font-medium text-xs text-dashboard-text-muted">
188
185
  52 weeks
189
186
  </div>
190
187
  }
@@ -213,7 +210,7 @@ function LeaderboardSection(props: {
213
210
  <ol className="m-0 list-none p-0">
214
211
  {props.items.slice(0, 6).map((item, index) => (
215
212
  <li
216
- className="grid min-w-0 grid-cols-[2rem_minmax(0,1fr)_auto] items-center gap-3 border-b border-white/[0.06] px-4 py-3 last:border-b-0"
213
+ className="grid min-w-0 grid-cols-[2rem_minmax(0,1fr)_auto] items-center gap-3 border-b border-dashboard-border-subtle px-4 py-3 last:border-b-0"
217
214
  key={item.label}
218
215
  >
219
216
  <div className="font-mono text-xs leading-none text-dashboard-text-muted">
@@ -56,7 +56,7 @@ function ProfilePluginReport(props: {
56
56
  {metrics.length ? (
57
57
  <div
58
58
  className={cn(
59
- "grid gap-px overflow-hidden rounded border border-white/[0.07] bg-white/[0.055]",
59
+ "grid gap-px overflow-hidden rounded-md border border-dashboard-border bg-dashboard-fill-hover",
60
60
  metrics.length === 1 ? "grid-cols-1" : "grid-cols-2",
61
61
  metrics.length === 3
62
62
  ? "lg:grid-cols-3"
@@ -81,7 +81,7 @@ function ProfilePluginReport(props: {
81
81
  <div className="truncate font-display text-2xl font-light leading-none text-dashboard-text">
82
82
  {metric.value}
83
83
  </div>
84
- <div className="mt-2 font-mono text-xs uppercase tracking-[0.1em] text-dashboard-text-muted">
84
+ <div className="mt-2 font-sans font-medium text-xs text-dashboard-text-muted">
85
85
  {metric.label}
86
86
  </div>
87
87
  </div>
@@ -31,11 +31,11 @@ function Stat(props: {
31
31
  valueClassName?: string;
32
32
  }) {
33
33
  return (
34
- <div className="rounded-md border border-white/[0.05] bg-black/10 px-3 py-3">
34
+ <div className="rounded-md border border-dashboard-border-subtle bg-dashboard-overlay-soft px-3 py-3">
35
35
  <div className="font-display text-xl font-light text-dashboard-text">
36
36
  <span className={props.valueClassName}>{props.value}</span>
37
37
  </div>
38
- <div className="mt-1 font-mono text-xs leading-relaxed text-dashboard-text-muted">
38
+ <div className="mt-1 font-sans text-xs leading-relaxed text-dashboard-text-muted">
39
39
  {props.label}
40
40
  </div>
41
41
  </div>
@@ -61,18 +61,18 @@ export function GuardianActivity(props: {
61
61
 
62
62
  return (
63
63
  <Card>
64
- <div className="border-b border-white/[0.06] px-4 py-4">
64
+ <div className="border-b border-dashboard-border-subtle px-4 py-4">
65
65
  <div className="flex flex-wrap items-start justify-between gap-3">
66
66
  <div>
67
- <h3 className="m-0 font-mono text-xs font-medium uppercase tracking-[0.14em] text-dashboard-text-muted">
67
+ <h3 className="m-0 font-sans text-xs font-medium text-dashboard-text-muted">
68
68
  Guardian reviews
69
69
  </h3>
70
- <p className="mt-1 mb-0 font-mono text-xs leading-relaxed text-dashboard-text-muted">
71
- {timeRangeBucketAdjective(bucketUnit)} decisions before
72
- reviewed actions execute.
70
+ <p className="mt-1 mb-0 font-sans text-xs leading-relaxed text-dashboard-text-muted">
71
+ {timeRangeBucketAdjective(bucketUnit)} decisions before reviewed
72
+ actions execute.
73
73
  </p>
74
74
  </div>
75
- <div className="font-mono text-xs uppercase tracking-[0.1em] text-dashboard-text-muted">
75
+ <div className="font-sans font-medium text-xs text-dashboard-text-muted">
76
76
  <span className="mr-3 text-emerald-200/75">Allow</span>
77
77
  <span className="mr-3 text-amber-200/75">Ask</span>
78
78
  <span className="text-rose-200/75">Deny</span>
@@ -131,7 +131,7 @@ export function GuardianActivity(props: {
131
131
  triggerClassName="h-full min-w-0 flex-1 items-end"
132
132
  >
133
133
  <button
134
- className="flex w-full min-w-0 flex-col justify-end overflow-hidden rounded-t-sm bg-white/[0.035] focus-visible:outline-1 focus-visible:outline-cyan-300"
134
+ className="flex w-full min-w-0 flex-col justify-end overflow-hidden rounded-t-sm bg-dashboard-fill-soft focus-visible:outline-1 focus-visible:outline-dashboard-focus"
135
135
  style={{ height: `${height}%` }}
136
136
  type="button"
137
137
  >
@@ -53,10 +53,10 @@ export function PluginBarChart(props: {
53
53
  const zeroY = layout.top + (maximum / span) * layout.plotHeight;
54
54
 
55
55
  return (
56
- <div className="overflow-hidden rounded border border-white/[0.07] bg-dashboard-surface-panel">
57
- <div className="border-b border-white/[0.06] px-4 py-3">
56
+ <div className="overflow-hidden rounded-md border border-dashboard-border bg-dashboard-surface-panel">
57
+ <div className="border-b border-dashboard-border-subtle px-4 py-3">
58
58
  <div className="flex flex-wrap items-start justify-between gap-3">
59
- <h4 className="m-0 font-mono text-xs font-medium uppercase tracking-[0.14em] text-dashboard-text-muted">
59
+ <h4 className="m-0 font-sans text-xs font-medium text-dashboard-text-muted">
60
60
  {widget.title}
61
61
  </h4>
62
62
  </div>
@@ -79,7 +79,7 @@ export function PluginBarChart(props: {
79
79
  ) : null}
80
80
  </div>
81
81
  {categories.length === 0 ? (
82
- <p className="m-0 p-4 font-mono text-xs text-dashboard-text-muted">
82
+ <p className="m-0 p-4 font-sans text-xs text-dashboard-text-muted">
83
83
  {widget.emptyText ?? "No chart data."}
84
84
  </p>
85
85
  ) : (
@@ -184,8 +184,6 @@ function visibleCategoryCount(
184
184
  return availableRanges.includes(30) ? 30 : (availableRanges[0] ?? 30);
185
185
  }
186
186
 
187
-
188
-
189
187
  function formatChartNumber(value: number): string {
190
188
  return String(Number(value.toPrecision(12)));
191
189
  }
@@ -14,7 +14,7 @@ export function PluginDetails(props: { plugin: SystemPlugin }) {
14
14
  title="Details"
15
15
  />
16
16
  <Card>
17
- <div className="grid grid-cols-1 gap-px bg-white/[0.055] sm:grid-cols-3">
17
+ <div className="grid grid-cols-1 gap-px bg-dashboard-fill-hover sm:grid-cols-3">
18
18
  <Detail icon={Boxes} label="Identifier" value={props.plugin.name} />
19
19
  <Detail
20
20
  icon={Sparkles}
@@ -27,7 +27,7 @@ export function PluginDetails(props: { plugin: SystemPlugin }) {
27
27
  value={String(props.plugin.configKeys.length)}
28
28
  />
29
29
  </div>
30
- <div className="grid gap-5 border-t border-white/[0.06] p-4 sm:p-5 lg:grid-cols-2">
30
+ <div className="grid gap-5 border-t border-dashboard-border-subtle p-4 sm:p-5 lg:grid-cols-2">
31
31
  <CapabilityList
32
32
  emptyText="No plugin-provided skills were discovered."
33
33
  items={props.plugin.skills.map((skill) => skill.name)}
@@ -52,12 +52,16 @@ function Detail(props: { icon: typeof Boxes; label: string; value: string }) {
52
52
  const Icon = props.icon;
53
53
  return (
54
54
  <div className="flex items-center gap-3 bg-dashboard-surface-panel px-4 py-3.5">
55
- <Icon aria-hidden="true" className="text-cyan-200/60" size={15} />
55
+ <Icon
56
+ aria-hidden="true"
57
+ className="text-dashboard-accent-text/60"
58
+ size={15}
59
+ />
56
60
  <div className="min-w-0">
57
61
  <div className="truncate font-display text-base font-medium text-dashboard-text">
58
62
  {props.value}
59
63
  </div>
60
- <div className="mt-0.5 font-mono text-xs uppercase tracking-[0.1em] text-dashboard-text-muted">
64
+ <div className="mt-0.5 font-sans font-medium text-xs text-dashboard-text-muted">
61
65
  {props.label}
62
66
  </div>
63
67
  </div>
@@ -72,14 +76,14 @@ function CapabilityList(props: {
72
76
  }) {
73
77
  return (
74
78
  <div>
75
- <h3 className="m-0 font-mono text-xs font-medium uppercase tracking-[0.12em] text-dashboard-text-muted">
79
+ <h3 className="m-0 font-sans text-xs font-medium text-dashboard-text-muted">
76
80
  {props.title}
77
81
  </h3>
78
82
  {props.items.length ? (
79
83
  <div className="mt-2.5 flex flex-wrap gap-2">
80
84
  {props.items.map((item) => (
81
85
  <span
82
- className="rounded border border-white/[0.07] bg-black/20 px-2.5 py-1.5 font-mono text-xs text-dashboard-text-muted"
86
+ className="rounded-md border border-dashboard-border bg-dashboard-overlay-soft px-2.5 py-1.5 font-mono text-xs text-dashboard-text-muted"
83
87
  key={item}
84
88
  >
85
89
  {item}
@@ -87,7 +91,7 @@ function CapabilityList(props: {
87
91
  ))}
88
92
  </div>
89
93
  ) : (
90
- <p className="mt-2 mb-0 font-mono text-xs leading-relaxed text-dashboard-text-muted">
94
+ <p className="mt-2 mb-0 font-sans text-xs leading-relaxed text-dashboard-text-muted">
91
95
  {props.emptyText}
92
96
  </p>
93
97
  )}
@@ -31,26 +31,26 @@ function PluginPanel(props: { plugin: SystemPlugin }) {
31
31
  );
32
32
  return (
33
33
  <Link
34
- className="group grid min-w-0 gap-4 rounded-lg border border-white/[0.07] bg-dashboard-surface-panel/85 p-4 no-underline transition-colors hover:border-cyan-300/20 hover:bg-cyan-300/[0.025] sm:p-5"
34
+ className="group grid min-w-0 gap-4 rounded-lg border border-dashboard-border bg-dashboard-surface-panel/85 p-4 no-underline transition-colors hover:border-dashboard-accent/20 hover:bg-dashboard-accent/[0.025] sm:p-5"
35
35
  to={systemPluginPath(props.plugin.name)}
36
36
  >
37
37
  <div className="flex min-w-0 items-start justify-between gap-4">
38
38
  <div className="flex min-w-0 items-start gap-3">
39
- <div className="grid size-9 shrink-0 place-items-center rounded border border-cyan-300/15 bg-cyan-300/[0.075] text-cyan-200">
39
+ <div className="grid size-9 shrink-0 place-items-center rounded-md border border-dashboard-accent/15 bg-dashboard-accent/[0.075] text-dashboard-accent-text">
40
40
  <Boxes aria-hidden="true" size={16} strokeWidth={1.8} />
41
41
  </div>
42
42
  <div className="min-w-0">
43
43
  <h3 className="m-0 truncate font-display text-lg font-medium text-dashboard-text">
44
44
  {props.plugin.displayName}
45
45
  </h3>
46
- <p className="mt-1 mb-0 line-clamp-2 font-mono text-xs leading-relaxed text-dashboard-text-muted">
46
+ <p className="mt-1 mb-0 line-clamp-2 font-sans text-xs leading-relaxed text-dashboard-text-muted">
47
47
  {props.plugin.description}
48
48
  </p>
49
49
  </div>
50
50
  </div>
51
51
  <ArrowRight
52
52
  aria-hidden="true"
53
- className="mt-1 shrink-0 text-dashboard-text-muted transition-transform group-hover:translate-x-0.5 group-hover:text-cyan-200/70"
53
+ className="mt-1 shrink-0 text-dashboard-text-muted transition-transform group-hover:translate-x-0.5 group-hover:text-dashboard-accent-text/70"
54
54
  size={16}
55
55
  />
56
56
  </div>
@@ -59,7 +59,7 @@ function PluginPanel(props: { plugin: SystemPlugin }) {
59
59
  <div
60
60
  className={`grid ${
61
61
  metrics.length === 1 ? "grid-cols-1" : "grid-cols-2"
62
- } gap-px overflow-hidden rounded border border-white/[0.06] bg-white/[0.055]`}
62
+ } gap-px overflow-hidden rounded-md border border-dashboard-border-subtle bg-dashboard-fill-hover`}
63
63
  >
64
64
  {metrics.slice(0, 2).map((metric) => (
65
65
  <div
@@ -69,7 +69,7 @@ function PluginPanel(props: { plugin: SystemPlugin }) {
69
69
  <div className="truncate font-display text-lg font-light text-dashboard-text">
70
70
  {metric.value}
71
71
  </div>
72
- <div className="mt-1 truncate font-mono text-xs uppercase tracking-[0.1em] text-dashboard-text-muted">
72
+ <div className="mt-1 truncate font-sans font-medium text-xs text-dashboard-text-muted">
73
73
  {metric.label}
74
74
  </div>
75
75
  </div>
@@ -77,7 +77,7 @@ function PluginPanel(props: { plugin: SystemPlugin }) {
77
77
  </div>
78
78
  ) : null}
79
79
 
80
- <div className="flex flex-wrap items-center gap-x-4 gap-y-2 border-t border-white/[0.055] pt-3">
80
+ <div className="flex flex-wrap items-center gap-x-4 gap-y-2 border-t border-dashboard-border-subtle pt-3">
81
81
  <PanelFact
82
82
  icon={Sparkles}
83
83
  label={`${props.plugin.skills.length} skills`}
@@ -90,7 +90,7 @@ function PluginPanel(props: { plugin: SystemPlugin }) {
90
90
  function PanelFact(props: { icon: typeof Sparkles; label: string }) {
91
91
  const Icon = props.icon;
92
92
  return (
93
- <span className="inline-flex items-center gap-1.5 font-mono text-xs uppercase tracking-[0.08em] text-dashboard-text-muted">
93
+ <span className="inline-flex items-center gap-1.5 font-sans font-medium text-xs text-dashboard-text-muted">
94
94
  <Icon aria-hidden="true" size={11} />
95
95
  {props.label}
96
96
  </span>
@@ -19,12 +19,12 @@ export function PluginReportRecordSet(props: {
19
19
  <div
20
20
  className={cn(
21
21
  embedded
22
- ? "border-t border-white/[0.06]"
23
- : "overflow-hidden rounded border border-white/[0.07] bg-dashboard-surface-panel",
22
+ ? "border-t border-dashboard-border-subtle"
23
+ : "overflow-hidden rounded-md border border-dashboard-border bg-dashboard-surface-panel",
24
24
  )}
25
25
  >
26
26
  <div className="flex items-center justify-between gap-4 px-5 py-3">
27
- <div className="font-mono text-xs uppercase tracking-[0.12em] text-dashboard-text-muted">
27
+ <div className="font-sans font-medium text-xs text-dashboard-text-muted">
28
28
  {props.recordSet.title}
29
29
  </div>
30
30
  <div className="hidden font-mono text-xs text-dashboard-text-muted sm:block">
@@ -32,30 +32,30 @@ export function PluginReportRecordSet(props: {
32
32
  </div>
33
33
  </div>
34
34
  {records.length === 0 ? (
35
- <div className="px-5 pb-5 font-mono text-xs leading-relaxed text-dashboard-text-muted">
35
+ <div className="px-5 pb-5 font-sans text-xs leading-relaxed text-dashboard-text-muted">
36
36
  {props.recordSet.emptyText ?? "No records."}
37
37
  </div>
38
38
  ) : fields.length === 0 ? (
39
- <div className="px-5 pb-5 font-mono text-xs leading-relaxed text-dashboard-text-muted">
39
+ <div className="px-5 pb-5 font-sans text-xs leading-relaxed text-dashboard-text-muted">
40
40
  Report records are unavailable because no fields were declared.
41
41
  </div>
42
42
  ) : (
43
43
  <>
44
- <div className="grid gap-2 border-t border-white/[0.05] p-3 sm:hidden">
44
+ <div className="grid gap-2 border-t border-dashboard-border-subtle p-3 sm:hidden">
45
45
  {records.map((record) => (
46
46
  <div
47
47
  className={cn(
48
- "grid gap-3 rounded-md border border-white/[0.06] bg-black/15 p-3",
48
+ "grid gap-3 rounded-md border border-dashboard-border-subtle bg-dashboard-overlay-soft p-3",
49
49
  rowToneClass(record.tone),
50
50
  )}
51
51
  key={record.id}
52
52
  >
53
53
  {fields.map((field) => (
54
54
  <div key={field.key}>
55
- <div className="font-mono text-xs uppercase tracking-[0.1em] text-dashboard-text-muted">
55
+ <div className="font-sans font-medium text-xs text-dashboard-text-muted">
56
56
  {field.label}
57
57
  </div>
58
- <div className="mt-1 break-words font-mono text-xs leading-relaxed text-dashboard-text-muted">
58
+ <div className="mt-1 break-words font-sans text-xs leading-relaxed text-dashboard-text-muted">
59
59
  {record.values[field.key] ?? ""}
60
60
  </div>
61
61
  </div>
@@ -63,13 +63,13 @@ export function PluginReportRecordSet(props: {
63
63
  </div>
64
64
  ))}
65
65
  </div>
66
- <div className="hidden overflow-x-auto border-t border-white/[0.05] sm:block">
66
+ <div className="hidden overflow-x-auto border-t border-dashboard-border-subtle sm:block">
67
67
  <table className="w-full min-w-[36rem] border-collapse text-left">
68
- <thead className="bg-black/15 font-mono text-xs uppercase tracking-[0.1em] text-dashboard-text-muted">
68
+ <thead className="bg-dashboard-overlay-soft font-sans font-medium text-xs text-dashboard-text-muted">
69
69
  <tr>
70
70
  {fields.map((field) => (
71
71
  <th
72
- className="border-b border-white/[0.055] px-5 py-2.5 font-medium"
72
+ className="border-b border-dashboard-border-subtle px-5 py-2.5 font-medium"
73
73
  key={field.key}
74
74
  scope="col"
75
75
  >
@@ -82,14 +82,14 @@ export function PluginReportRecordSet(props: {
82
82
  {records.map((record) => (
83
83
  <tr
84
84
  className={cn(
85
- "transition-colors hover:bg-white/[0.025]",
85
+ "transition-colors hover:bg-dashboard-fill-soft",
86
86
  rowToneClass(record.tone),
87
87
  )}
88
88
  key={record.id}
89
89
  >
90
90
  {fields.map((field) => (
91
91
  <td
92
- className="max-w-72 truncate border-b border-white/[0.05] px-5 py-3 font-mono text-xs text-dashboard-text-muted"
92
+ className="max-w-72 truncate border-b border-dashboard-border-subtle px-5 py-3 font-mono text-xs text-dashboard-text-muted"
93
93
  key={field.key}
94
94
  >
95
95
  {record.values[field.key] ?? ""}
@@ -21,14 +21,14 @@ export function PluginReports(props: {
21
21
  return (
22
22
  <Card padding="md">
23
23
  <div className="flex items-center gap-4">
24
- <div className="grid size-10 shrink-0 place-items-center rounded border border-white/[0.07] bg-white/[0.025] text-dashboard-text-muted">
24
+ <div className="grid size-10 shrink-0 place-items-center rounded-md border border-dashboard-border bg-dashboard-fill-soft text-dashboard-text-muted">
25
25
  <RadioTower aria-hidden="true" size={17} />
26
26
  </div>
27
27
  <div>
28
28
  <h2 className="m-0 font-display text-base font-medium text-dashboard-text-muted">
29
29
  Operational reports
30
30
  </h2>
31
- <p className="mt-1 mb-0 font-mono text-xs leading-relaxed text-dashboard-text-muted">
31
+ <p className="mt-1 mb-0 font-sans text-xs leading-relaxed text-dashboard-text-muted">
32
32
  {props.emptyText}
33
33
  </p>
34
34
  </div>
@@ -39,10 +39,7 @@ export function PluginReports(props: {
39
39
 
40
40
  return (
41
41
  <div className="grid gap-3">
42
- <SectionIntro
43
- className="px-1"
44
- title="Operational reports"
45
- />
42
+ <SectionIntro className="px-1" title="Operational reports" />
46
43
  {props.reports.map((report) => (
47
44
  <PluginReportView
48
45
  fallbackTitle={props.fallbackTitle}
@@ -68,7 +65,7 @@ function PluginReportView(props: {
68
65
  const metrics = props.report.metrics ?? [];
69
66
  return (
70
67
  <Card>
71
- <div className="flex items-start justify-between gap-4 border-b border-white/[0.06] px-5 py-4">
68
+ <div className="flex items-start justify-between gap-4 border-b border-dashboard-border-subtle px-5 py-4">
72
69
  <div className="min-w-0">
73
70
  <h3 className="m-0 truncate font-display text-lg font-medium text-dashboard-text">
74
71
  {title}
@@ -86,7 +83,7 @@ function PluginReportView(props: {
86
83
  {metrics.length ? (
87
84
  <div
88
85
  className={cn(
89
- "grid gap-px bg-white/[0.055]",
86
+ "grid gap-px bg-dashboard-fill-hover",
90
87
  metrics.length === 1 ? "grid-cols-1" : "grid-cols-2",
91
88
  metrics.length === 3
92
89
  ? "lg:grid-cols-3"
@@ -111,7 +108,7 @@ function PluginReportView(props: {
111
108
  <div className="truncate font-display text-2xl font-light leading-none text-dashboard-text">
112
109
  {metric.value}
113
110
  </div>
114
- <div className="mt-2 font-mono text-xs uppercase tracking-[0.1em] text-dashboard-text-muted">
111
+ <div className="mt-2 font-sans font-medium text-xs text-dashboard-text-muted">
115
112
  {metric.label}
116
113
  </div>
117
114
  </div>
@@ -119,7 +116,7 @@ function PluginReportView(props: {
119
116
  </div>
120
117
  ) : null}
121
118
  {props.report.widgets?.length ? (
122
- <div className="grid gap-3 border-t border-white/[0.06] bg-black/15 p-3 lg:grid-cols-2">
119
+ <div className="grid gap-3 border-t border-dashboard-border-subtle bg-dashboard-overlay-soft p-3 lg:grid-cols-2">
123
120
  {props.report.widgets.map((widget) => (
124
121
  <PluginBarChart
125
122
  key={widget.id}
@@ -146,4 +143,3 @@ function summaryToneClass(tone: string | undefined): string {
146
143
  if (tone === "good") return "shadow-[inset_0_2px_0_rgba(110,231,183,0.55)]";
147
144
  return "";
148
145
  }
149
-