@sentry/junior-dashboard 0.265.0 → 0.267.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 (104) hide show
  1. package/dist/app.js +49 -12
  2. package/dist/client.js +94 -63
  3. package/dist/index.js +49 -12
  4. package/dist/tailwind.css +1 -1
  5. package/package.json +11 -5
  6. package/src/app.ts +0 -2
  7. package/src/auth.ts +4 -7
  8. package/src/client/App.tsx +35 -53
  9. package/src/client/components/ActorAvatar.tsx +10 -22
  10. package/src/client/components/ConnectionBanner.tsx +4 -3
  11. package/src/client/components/CopyButton.tsx +3 -4
  12. package/src/client/components/DetailsPanel.tsx +12 -13
  13. package/src/client/components/Drawer.tsx +46 -23
  14. package/src/client/components/EmptyTelemetry.tsx +5 -3
  15. package/src/client/components/ImageAttachment.tsx +49 -63
  16. package/src/client/components/InlineError.tsx +8 -4
  17. package/src/client/components/Notice.tsx +19 -26
  18. package/src/client/components/Pagination.tsx +26 -26
  19. package/src/client/components/ParticipantAvatarStack.tsx +13 -10
  20. package/src/client/components/README.md +28 -3
  21. package/src/client/components/SearchInput.tsx +51 -41
  22. package/src/client/components/VersionDriftBanner.tsx +9 -7
  23. package/src/client/components/charts/CacheWrites.tsx +52 -43
  24. package/src/client/components/ui/alert.tsx +64 -0
  25. package/src/client/components/ui/avatar.tsx +53 -0
  26. package/src/client/components/ui/button-group.tsx +59 -0
  27. package/src/client/components/ui/button.tsx +2 -1
  28. package/src/client/components/ui/dialog.tsx +60 -0
  29. package/src/client/components/ui/drawer.tsx +140 -0
  30. package/src/client/components/ui/empty.tsx +61 -0
  31. package/src/client/components/ui/input-group.tsx +96 -0
  32. package/src/client/components/ui/pagination.tsx +60 -0
  33. package/src/client/components/ui/separator.tsx +22 -0
  34. package/src/client/components/ui/spinner.tsx +21 -0
  35. package/src/client/components/ui/table.tsx +22 -1
  36. package/src/client/components/ui/tooltip.tsx +1 -1
  37. package/src/client/components/ui/useSheet.ts +5 -1
  38. package/src/client/conversations/ComposerImages.tsx +66 -14
  39. package/src/client/conversations/ConversationChildAgents.tsx +5 -5
  40. package/src/client/conversations/ConversationComposer.tsx +84 -12
  41. package/src/client/conversations/ConversationDetails.tsx +3 -27
  42. package/src/client/conversations/ConversationEventDetails.tsx +26 -10
  43. package/src/client/conversations/ConversationHeader.tsx +5 -4
  44. package/src/client/conversations/ConversationHeaderActions.tsx +7 -11
  45. package/src/client/conversations/ConversationPage.tsx +156 -2
  46. package/src/client/conversations/ConversationSidebar.tsx +5 -4
  47. package/src/client/conversations/ConversationTranscript.tsx +48 -16
  48. package/src/client/conversations/ConversationUsageBreakdown.tsx +108 -65
  49. package/src/client/conversations/ConversationWatches.tsx +67 -59
  50. package/src/client/conversations/DetailsList.tsx +77 -29
  51. package/src/client/conversations/EventDetails.tsx +46 -19
  52. package/src/client/conversations/EventUsage.tsx +99 -74
  53. package/src/client/conversations/ForkConversationButton.tsx +79 -73
  54. package/src/client/conversations/PendingMailboxStack.tsx +312 -119
  55. package/src/client/conversations/README.md +30 -10
  56. package/src/client/conversations/ShareConversationButton.tsx +3 -4
  57. package/src/client/conversations/SubagentTranscriptDrawer.tsx +19 -22
  58. package/src/client/conversations/TranscriptActivityGroup.tsx +22 -19
  59. package/src/client/conversations/TranscriptAttachment.tsx +39 -4
  60. package/src/client/conversations/TranscriptAutomationTriggerView.tsx +14 -19
  61. package/src/client/conversations/TranscriptEventView.tsx +35 -16
  62. package/src/client/conversations/TranscriptFailureView.tsx +10 -13
  63. package/src/client/conversations/TranscriptMarkdown.tsx +232 -436
  64. package/src/client/conversations/TranscriptMessageContextView.tsx +31 -20
  65. package/src/client/conversations/TranscriptMessageView.tsx +7 -1
  66. package/src/client/conversations/TranscriptStructuredEventView.tsx +25 -15
  67. package/src/client/conversations/TranscriptSummary.tsx +13 -7
  68. package/src/client/conversations/TranscriptTurnContextView.tsx +78 -56
  69. package/src/client/conversations/TranscriptView.tsx +7 -3
  70. package/src/client/conversations/UserInputRequestCard.tsx +244 -0
  71. package/src/client/conversations/conversationOutbox.ts +46 -0
  72. package/src/client/conversations/eventLog.ts +1 -0
  73. package/src/client/conversations/eventTime.ts +13 -1
  74. package/src/client/conversations/eventTranscript.ts +12 -5
  75. package/src/client/conversations/queries.ts +127 -26
  76. package/src/client/conversations/transcriptMarkdownLinks.ts +5 -367
  77. package/src/client/conversations/transcriptMentions.tsx +18 -5
  78. package/src/client/conversations/userInputRequest.ts +56 -0
  79. package/src/client/format.ts +10 -3
  80. package/src/client/pages/automations/{AutomationLifecycle.tsx → AutomationActions.tsx} +60 -69
  81. package/src/client/pages/automations/AutomationDraftChanges.tsx +171 -0
  82. package/src/client/pages/automations/AutomationEditor.tsx +182 -156
  83. package/src/client/pages/automations/AutomationEventFields.tsx +119 -45
  84. package/src/client/pages/automations/AutomationExecutionStatusChart.tsx +1 -1
  85. package/src/client/pages/automations/AutomationFormSection.tsx +20 -2
  86. package/src/client/pages/automations/AutomationOutcomeFields.tsx +1 -1
  87. package/src/client/pages/automations/AutomationOverview.tsx +238 -0
  88. package/src/client/pages/automations/AutomationPage.tsx +343 -0
  89. package/src/client/pages/automations/AutomationRecentRuns.tsx +3 -2
  90. package/src/client/pages/automations/AutomationRow.tsx +11 -13
  91. package/src/client/pages/automations/AutomationRunDetails.tsx +4 -2
  92. package/src/client/pages/automations/{AutomationExecutionsPage.tsx → AutomationRunsTab.tsx} +94 -103
  93. package/src/client/pages/automations/AutomationStatus.tsx +164 -108
  94. package/src/client/pages/automations/AutomationVersionsTab.tsx +518 -0
  95. package/src/client/pages/automations/AutomationsPage.tsx +10 -98
  96. package/src/client/pages/automations/AutomationsPageLayout.tsx +5 -23
  97. package/src/client/pages/automations/README.md +56 -46
  98. package/src/client/types.ts +3 -0
  99. package/src/mock-reporting/fixtures.ts +44 -2
  100. package/src/mock-reporting/watches.ts +1 -1
  101. package/src/client/conversations/transcriptStyles.ts +0 -10
  102. package/src/client/pages/automations/AutomationDetails.tsx +0 -193
  103. package/src/client/pages/automations/AutomationEditPage.tsx +0 -176
  104. package/src/client/pages/automations/AutomationVersionsPage.tsx +0 -390
@@ -10,129 +10,185 @@ import {
10
10
  import { FormNotice } from "../../components/FormNotice";
11
11
  import { StatusChip } from "../../components/StatusChip";
12
12
  import { conversationPath } from "../../conversations/conversationRoutes";
13
- import { formatRelativeTime } from "../../format";
14
- import { dashboardInlineLinkClass } from "../../styles";
13
+ import { automationPath, formatRelativeTime } from "../../format";
14
+ import { buttonVariants } from "../../components/ui/button";
15
+ import { cn } from "../../styles";
15
16
  import { formatAutomationRunTime } from "./automationFormat";
16
17
 
17
- /** Separate the Automation's lifecycle, next trigger, and last execution result. */
18
+ /**
19
+ * Name the lifecycle state. It is a live region, so Pause and Resume results
20
+ * are announced.
21
+ */
22
+ export function AutomationStateChip({
23
+ automation,
24
+ }: {
25
+ automation: AutomationSummary;
26
+ }) {
27
+ const unavailable =
28
+ automation.kind === "event" && automation.trigger.problems.length > 0;
29
+ return (
30
+ <span aria-label="Automation state" aria-live="polite" role="status">
31
+ <StatusChip
32
+ size="compact"
33
+ tone={
34
+ automation.status === "paused" || automation.status === "completed"
35
+ ? "neutral"
36
+ : automation.status === "blocked" || unavailable
37
+ ? "warning"
38
+ : "success"
39
+ }
40
+ >
41
+ {automation.status === "active" && unavailable
42
+ ? "Trigger unavailable"
43
+ : automation.status}
44
+ </StatusChip>
45
+ </span>
46
+ );
47
+ }
48
+
49
+ /** Show the next trigger and the last execution result. */
18
50
  export function AutomationStatus({
19
51
  automation,
20
52
  }: {
21
53
  automation: AutomationSummary;
22
54
  }) {
55
+ const lastResult = automation.lastRunStatus
56
+ ? `Last run ${automation.lastRunStatus}`
57
+ : "Last run";
58
+ return (
59
+ <div className="grid gap-1.5">
60
+ <AutomationNextTrigger automation={automation} />
61
+ <p className="m-0 text-xs text-dashboard-text-muted">
62
+ {automation.lastRunAt ? (
63
+ <>
64
+ {lastResult} ·{" "}
65
+ <time
66
+ dateTime={automation.lastRunAt}
67
+ title={formatAutomationRunTime(automation.lastRunAt)}
68
+ >
69
+ {formatRelativeTime(automation.lastRunAt)}
70
+ </time>
71
+ </>
72
+ ) : automation.lastRunStatus ? (
73
+ `${lastResult} · time not recorded`
74
+ ) : automation.totalRuns === 0 ? (
75
+ "No runs yet"
76
+ ) : (
77
+ "Last run time not recorded"
78
+ )}
79
+ </p>
80
+ </div>
81
+ );
82
+ }
83
+
84
+ /** Name the one problem the Overview notice explains, if there is one. */
85
+ function automationProblem(automation: AutomationSummary) {
86
+ if (
87
+ automation.status === "blocked" ||
88
+ (automation.status === "paused" && automation.statusReason)
89
+ )
90
+ return "fix";
91
+ if (automation.kind === "event" && automation.trigger.problems.length > 0)
92
+ return "trigger";
93
+ if (
94
+ automation.lastRunStatus === "failed" ||
95
+ automation.lastRunStatus === "blocked"
96
+ )
97
+ return "last_run";
98
+ return undefined;
99
+ }
100
+
101
+ /** True when the Overview shows a notice, so the notice owns the main action. */
102
+ export function automationNeedsAttention(
103
+ automation: AutomationSummary,
104
+ ): boolean {
105
+ return automationProblem(automation) !== undefined;
106
+ }
107
+
108
+ /**
109
+ * Explain one problem that needs action and offer one fix: a block, an
110
+ * unavailable trigger, or a failed last run. Renders nothing when the
111
+ * Automation is healthy.
112
+ */
113
+ export function AutomationAttention({
114
+ automation,
115
+ editPath,
116
+ }: {
117
+ automation: AutomationSummary;
118
+ editPath: string;
119
+ }) {
120
+ const problem = automationProblem(automation);
121
+ if (!problem) return null;
23
122
  const paused = automation.status === "paused";
24
- const blocked = automation.status === "blocked";
25
- const completed = automation.status === "completed";
26
123
  const triggerProblems =
27
124
  automation.kind === "event" ? automation.trigger.problems : [];
125
+ const needsFix = problem === "fix";
126
+ // A blocked Automation still lists trigger problems, and Change trigger fixes it.
28
127
  const unavailable = triggerProblems.length > 0;
29
- const failed =
30
- automation.lastRunStatus === "failed" ||
31
- automation.lastRunStatus === "blocked";
32
- const needsFix = blocked || (paused && Boolean(automation.statusReason));
33
- const showAttention = needsFix || unavailable || failed;
34
- const lastResult = automation.lastRunStatus
35
- ? `Last run ${automation.lastRunStatus}`
36
- : "Last run";
128
+ const failed = problem === "last_run";
37
129
  return (
38
- <div className="grid gap-3">
39
- <div className="grid gap-1.5">
40
- <div aria-label="Automation state" aria-live="polite" role="status">
41
- <StatusChip
42
- tone={
43
- paused || completed
44
- ? "neutral"
45
- : blocked || unavailable
46
- ? "warning"
47
- : "success"
48
- }
49
- >
50
- {automation.status === "active" && unavailable
51
- ? "Trigger unavailable"
52
- : automation.status}
53
- </StatusChip>
54
- </div>
55
- <AutomationNextTrigger automation={automation} />
56
- <p className="m-0 text-xs text-dashboard-text-muted">
57
- {automation.lastRunAt ? (
58
- <>
59
- {lastResult} ·{" "}
60
- <time
61
- dateTime={automation.lastRunAt}
62
- title={formatAutomationRunTime(automation.lastRunAt)}
63
- >
64
- {formatRelativeTime(automation.lastRunAt)}
65
- </time>
66
- </>
67
- ) : automation.lastRunStatus ? (
68
- `${lastResult} · time not recorded`
69
- ) : automation.totalRuns === 0 ? (
70
- "No runs yet"
71
- ) : (
72
- "Last run time not recorded"
73
- )}
130
+ <FormNotice
131
+ title={
132
+ needsFix
133
+ ? "Fix this before resuming"
134
+ : unavailable
135
+ ? "Trigger unavailable"
136
+ : "Check the last run"
137
+ }
138
+ >
139
+ {needsFix ? (
140
+ <p className="m-0 break-words">
141
+ {automation.statusReason ??
142
+ "Check the last run to see what needs fixing."}{" "}
143
+ {!automation.ownedByViewer
144
+ ? `Ask ${automation.createdBy} to resume after this is fixed.`
145
+ : null}
74
146
  </p>
75
- </div>
76
- {showAttention ? (
77
- <FormNotice
78
- title={
79
- needsFix
80
- ? "Fix this before resuming"
81
- : unavailable
82
- ? "Trigger unavailable"
83
- : "Check the last run"
84
- }
147
+ ) : null}
148
+ {unavailable ? (
149
+ <>
150
+ <ul className="my-1 list-disc pl-5">
151
+ {triggerProblems.map((problem) => (
152
+ <li className="break-words" key={problem}>
153
+ {problem}
154
+ </li>
155
+ ))}
156
+ </ul>
157
+ <p className="m-0">Edit the trigger, or enable its plugin again.</p>
158
+ </>
159
+ ) : null}
160
+ {failed && !needsFix && !unavailable ? (
161
+ <p className="m-0">
162
+ {automation.status === "active"
163
+ ? "Future runs are still on."
164
+ : paused
165
+ ? "Review the last result before resuming."
166
+ : "Review the last result for details."}
167
+ </p>
168
+ ) : null}
169
+ {unavailable ? (
170
+ <Link
171
+ className={cn(buttonVariants({ variant: "primary" }), "mt-3")}
172
+ to={editPath}
85
173
  >
86
- {needsFix ? (
87
- <p className="m-0 break-words">
88
- {automation.statusReason ??
89
- "Check the last run to see what needs fixing."}{" "}
90
- {!automation.ownedByViewer
91
- ? `Ask ${automation.createdBy} to resume after this is fixed.`
92
- : null}
93
- </p>
94
- ) : null}
95
- {unavailable ? (
96
- <>
97
- <ul className="my-1 list-disc pl-5">
98
- {triggerProblems.map((problem) => (
99
- <li className="break-words" key={problem}>
100
- {problem}
101
- </li>
102
- ))}
103
- </ul>
104
- <p className="m-0">
105
- Edit the trigger, or enable its plugin again.
106
- </p>
107
- </>
108
- ) : null}
109
- {failed && !needsFix && !unavailable ? (
110
- <p className="m-0">
111
- {automation.status === "active"
112
- ? "Future runs are still on."
113
- : paused
114
- ? "Review the last result before resuming."
115
- : "Review the last result for details."}
116
- </p>
117
- ) : null}
118
- {automation.lastConversationId ? (
119
- <Link
120
- className={`${dashboardInlineLinkClass} mt-2 inline-block`}
121
- to={conversationPath(automation.lastConversationId)}
122
- >
123
- Open last run
124
- </Link>
125
- ) : automation.totalRuns > 0 ? (
126
- <Link
127
- className={`${dashboardInlineLinkClass} mt-2 inline-block`}
128
- to={`/automations/${encodeURIComponent(automation.id)}/executions`}
129
- >
130
- View run history
131
- </Link>
132
- ) : null}
133
- </FormNotice>
174
+ Change trigger
175
+ </Link>
176
+ ) : automation.lastConversationId ? (
177
+ <Link
178
+ className={cn(buttonVariants({ variant: "primary" }), "mt-3")}
179
+ to={conversationPath(automation.lastConversationId)}
180
+ >
181
+ Open last run
182
+ </Link>
183
+ ) : automation.totalRuns > 0 ? (
184
+ <Link
185
+ className={cn(buttonVariants({ variant: "primary" }), "mt-3")}
186
+ to={automationPath(automation.id, "runs")}
187
+ >
188
+ View run history
189
+ </Link>
134
190
  ) : null}
135
- </div>
191
+ </FormNotice>
136
192
  );
137
193
  }
138
194