@sentry/junior-dashboard 0.262.0 → 0.264.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.
@@ -118,6 +118,8 @@ export type TranscriptViewTurnContext = {
118
118
  export type TranscriptViewMessage = {
119
119
  cards?: MessageCard[];
120
120
  actorIdentity?: ActorIdentity;
121
+ /** Agent invocation whose input this is. An agent wrote it, not a person. */
122
+ agentInvocationId?: string;
121
123
  contexts?: TranscriptViewTurnContext[];
122
124
  /** Mailbox delivery mode while the message is still pending history commit. */
123
125
  delivery?: "defer" | "interrupt";
@@ -1002,6 +1002,9 @@ function advisorConversation(
1002
1002
  const conversation = detail(nowMs, {
1003
1003
  conversationId,
1004
1004
  displayTitle: "Advisor review",
1005
+ // A child keeps the Actor who started it, but that person did not write
1006
+ // its agent invocation input.
1007
+ actorIdentity: actor("dev@example.com", "Morgan Lee", "morgan"),
1005
1008
  startedAt,
1006
1009
  lastSeenAt: iso(Date.parse(startedAt), 18_000),
1007
1010
  lastProgressAt: iso(Date.parse(startedAt), 18_000),
@@ -1011,6 +1014,7 @@ function advisorConversation(
1011
1014
  type: "message",
1012
1015
  messageId: `${conversationId}:input`,
1013
1016
  role: "user",
1017
+ agentInvocationId: `${conversationId}:invocation`,
1014
1018
  text,
1015
1019
  }),
1016
1020
  reportEvent(1, iso(Date.parse(startedAt), 18_000), {
package/src/tailwind.css CHANGED
@@ -1,5 +1,7 @@
1
1
  @import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Outfit:wght@300;400;500;600;700&display=swap");
2
2
  @import "tailwindcss";
3
+ @import "tw-animate-css";
4
+ @import "shadcn/tailwind.css";
3
5
 
4
6
  /*
5
7
  * Dashboard design tokens. components/README.md explains each role.
@@ -214,6 +216,81 @@
214
216
  --color-violet-400: oklch(54.1% 0.281 293.009);
215
217
  }
216
218
 
219
+ /* shadcn components use the dashboard tokens in both themes. */
220
+ @layer base {
221
+ :root {
222
+ --radius: 0.5rem;
223
+ --background: var(--color-dashboard-bg);
224
+ --foreground: var(--color-dashboard-text);
225
+ --card: var(--color-dashboard-surface-panel);
226
+ --card-foreground: var(--color-dashboard-text);
227
+ --popover: var(--color-dashboard-bg-elevated);
228
+ --popover-foreground: var(--color-dashboard-text);
229
+ --primary: var(--color-dashboard-text-solid);
230
+ --primary-foreground: var(--color-dashboard-text-inverse);
231
+ --secondary: var(--color-dashboard-surface-raised);
232
+ --secondary-foreground: var(--color-dashboard-text);
233
+ --muted: var(--color-dashboard-surface-raised);
234
+ --muted-foreground: var(--color-dashboard-text-muted);
235
+ --accent: var(--color-dashboard-surface-hover);
236
+ --accent-foreground: var(--color-dashboard-text);
237
+ --destructive: var(--color-rose-300);
238
+ --border: var(--color-dashboard-border);
239
+ --input: var(--color-dashboard-border-emphasis);
240
+ --ring: var(--color-dashboard-focus);
241
+ --chart-1: var(--color-violet-400);
242
+ --chart-2: var(--color-sky-400);
243
+ --chart-3: var(--color-emerald-400);
244
+ --chart-4: var(--color-amber-400);
245
+ --chart-5: var(--color-rose-400);
246
+ --sidebar: var(--color-dashboard-surface-panel);
247
+ --sidebar-foreground: var(--color-dashboard-text);
248
+ --sidebar-primary: var(--primary);
249
+ --sidebar-primary-foreground: var(--color-dashboard-text-inverse);
250
+ --sidebar-accent: var(--color-dashboard-surface-hover);
251
+ --sidebar-accent-foreground: var(--color-dashboard-text);
252
+ --sidebar-border: var(--color-dashboard-border);
253
+ --sidebar-ring: var(--color-dashboard-focus);
254
+ }
255
+ }
256
+
257
+ @theme inline {
258
+ --color-background: var(--background);
259
+ --color-foreground: var(--foreground);
260
+ --color-card: var(--card);
261
+ --color-card-foreground: var(--card-foreground);
262
+ --color-popover: var(--popover);
263
+ --color-popover-foreground: var(--popover-foreground);
264
+ --color-primary: var(--primary);
265
+ --color-primary-foreground: var(--primary-foreground);
266
+ --color-secondary: var(--secondary);
267
+ --color-secondary-foreground: var(--secondary-foreground);
268
+ --color-muted: var(--muted);
269
+ --color-muted-foreground: var(--muted-foreground);
270
+ --color-accent: var(--accent);
271
+ --color-accent-foreground: var(--accent-foreground);
272
+ --color-destructive: var(--destructive);
273
+ --color-border: var(--border);
274
+ --color-input: var(--input);
275
+ --color-ring: var(--ring);
276
+ --color-chart-1: var(--chart-1);
277
+ --color-chart-2: var(--chart-2);
278
+ --color-chart-3: var(--chart-3);
279
+ --color-chart-4: var(--chart-4);
280
+ --color-chart-5: var(--chart-5);
281
+ --color-sidebar: var(--sidebar);
282
+ --color-sidebar-foreground: var(--sidebar-foreground);
283
+ --color-sidebar-primary: var(--sidebar-primary);
284
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
285
+ --color-sidebar-accent: var(--sidebar-accent);
286
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
287
+ --color-sidebar-border: var(--sidebar-border);
288
+ --color-sidebar-ring: var(--sidebar-ring);
289
+ }
290
+
291
+ /* The dashboard defaults to dark and selects light with data-theme. */
292
+ @custom-variant dark (&:where(:root:not([data-theme="light"]), :root:not([data-theme="light"]) *));
293
+
217
294
  /* Style one-off values that the token and palette mirror cannot cover. */
218
295
  @custom-variant light (&:where([data-theme="light"], [data-theme="light"] *));
219
296
 
@@ -1,141 +0,0 @@
1
- // Adapted from shadcn/ui's Base UI Sheet. Drawer adds native swipe support.
2
- // https://ui.shadcn.com/docs/components/base/sheet
3
- import { Drawer as SheetPrimitive } from "@base-ui/react/drawer";
4
- import {
5
- createContext,
6
- useContext,
7
- useEffect,
8
- useRef,
9
- useState,
10
- useSyncExternalStore,
11
- type ReactNode,
12
- type RefObject,
13
- } from "react";
14
-
15
- import {
16
- acquireBodyScrollLock,
17
- releaseBodyScrollLock,
18
- } from "../bodyScrollLock";
19
- import { cn } from "../styles";
20
-
21
- const SheetContext = createContext<{
22
- closingRef: RefObject<boolean>;
23
- popupRef: RefObject<HTMLDivElement | null>;
24
- topmost: boolean;
25
- } | null>(null);
26
-
27
- // Separate roots can overlap when a resize mounts a sheet below an open drawer.
28
- // Only the last modal in document order may trap focus or handle dismissal.
29
- function subscribeToSheets(onChange: () => void) {
30
- const observer = new MutationObserver(onChange);
31
- observer.observe(document.body, { childList: true, subtree: true });
32
- return () => observer.disconnect();
33
- }
34
-
35
- /** Keep modal state until Base UI finishes its close transition. */
36
- export function Sheet(props: {
37
- children: ReactNode;
38
- onClose(): void;
39
- side: "right" | "bottom";
40
- }) {
41
- const [open, setOpen] = useState(false);
42
- const closingRef = useRef(false);
43
- const popupRef = useRef<HTMLDivElement>(null);
44
- const topmost = useSyncExternalStore(
45
- subscribeToSheets,
46
- () => {
47
- const modals = document.querySelectorAll("[data-dashboard-modal]");
48
- const last = modals[modals.length - 1];
49
- return popupRef.current ? last === popupRef.current : !last;
50
- },
51
- () => true,
52
- );
53
- useEffect(() => {
54
- // The mobile conversation shell uses this same document scroll lock.
55
- acquireBodyScrollLock();
56
- setOpen(true);
57
- return releaseBodyScrollLock;
58
- }, []);
59
-
60
- return (
61
- <SheetContext value={{ closingRef, popupRef, topmost }}>
62
- <SheetPrimitive.Root
63
- open={open}
64
- modal={topmost ? "trap-focus" : false}
65
- disablePointerDismissal={!topmost}
66
- swipeDirection={props.side === "bottom" ? "down" : "right"}
67
- onOpenChange={(open, details) => {
68
- if (!open && !topmost) {
69
- details.cancel();
70
- return;
71
- }
72
- closingRef.current = !open;
73
- setOpen(open);
74
- }}
75
- onOpenChangeComplete={(open) => {
76
- if (!open && closingRef.current) props.onClose();
77
- }}
78
- >
79
- {props.children}
80
- </SheetPrimitive.Root>
81
- </SheetContext>
82
- );
83
- }
84
-
85
- /** Close the enclosing sheet through its transition and focus lifecycle. */
86
- export const SheetClose = SheetPrimitive.Close;
87
-
88
- /** Render sheet chrome, a fading backdrop, and Base UI's focus boundary. */
89
- export function SheetContent(
90
- props: {
91
- children: ReactNode;
92
- className?: string;
93
- initialFocusRef?: RefObject<HTMLElement | null>;
94
- side: "right" | "bottom";
95
- } & ({ label: string; titleId?: never } | { label?: never; titleId: string }),
96
- ) {
97
- const sheet = useContext(SheetContext);
98
- const popupRef = sheet?.popupRef;
99
- const portalRef = useRef<HTMLDivElement>(null);
100
- return (
101
- <>
102
- <div ref={portalRef} className="contents" />
103
- <SheetPrimitive.Portal container={portalRef}>
104
- <SheetPrimitive.Backdrop className="fixed inset-0 z-50 bg-dashboard-overlay opacity-[calc(1-var(--drawer-swipe-progress,0))] transition-opacity duration-180 data-[ending-style]:opacity-0 data-[starting-style]:opacity-0 data-[swiping]:transition-none motion-reduce:transition-none" />
105
- <SheetPrimitive.Viewport className="pointer-events-none fixed inset-0 z-50">
106
- <SheetPrimitive.Popup
107
- ref={popupRef}
108
- aria-modal={sheet?.topmost ? true : undefined}
109
- aria-label={props.label}
110
- aria-labelledby={props.titleId}
111
- data-dashboard-modal=""
112
- data-base-ui-swipe-ignore={props.side === "right" ? "" : undefined}
113
- finalFocus={() =>
114
- Boolean(sheet?.closingRef.current && sheet.topmost)
115
- }
116
- initialFocus={() => {
117
- // A resize can mount a sheet beneath an existing event dialog.
118
- const modals = document.querySelectorAll(
119
- "[data-dashboard-modal]",
120
- );
121
- if (modals[modals.length - 1] !== popupRef?.current) return false;
122
- return props.initialFocusRef?.current ?? true;
123
- }}
124
- className={cn(
125
- "pointer-events-auto grid min-h-0 min-w-0 grid-rows-[auto_minmax(0,1fr)] bg-dashboard-bg-elevated outline-none transition-[opacity,transform] duration-180 ease-[cubic-bezier(0.2,0.8,0.2,1)] data-[ending-style]:opacity-0 data-[starting-style]:opacity-0 data-[swiping]:transition-none motion-reduce:transition-none",
126
- props.side === "bottom"
127
- ? "absolute inset-x-0 bottom-0 mx-auto h-[85dvh] max-h-full w-full max-w-2xl [transform:translateY(var(--drawer-swipe-movement-y,0px))] rounded-t-2xl border border-b-0 border-dashboard-border-strong shadow-[0_-12px_40px_rgba(0,0,0,0.25)] data-[ending-style]:[transform:translateY(100%)] data-[starting-style]:[transform:translateY(2.5rem)]"
128
- : "absolute right-0 top-0 h-full w-full shadow-[-12px_0_40px_rgba(0,0,0,0.25)] data-[ending-style]:[transform:translateX(2.5rem)] data-[starting-style]:[transform:translateX(2.5rem)] md:border-l md:border-dashboard-border-strong",
129
- props.className,
130
- )}
131
- >
132
- {props.children}
133
- </SheetPrimitive.Popup>
134
- </SheetPrimitive.Viewport>
135
- </SheetPrimitive.Portal>
136
- </>
137
- );
138
- }
139
-
140
- /** Keep text selection and scrolling separate from the swipe handle. */
141
- export const SheetBody = SheetPrimitive.Content;