@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.
- package/dist/app.js +6 -2
- package/dist/client.js +62 -58
- package/dist/index.js +6 -2
- package/dist/tailwind.css +1 -1
- package/package.json +7 -3
- package/src/client/components/BottomSheet.tsx +16 -18
- package/src/client/components/Drawer.tsx +22 -12
- package/src/client/components/README.md +37 -9
- package/src/client/components/ui/sheet.tsx +141 -0
- package/src/client/components/ui/useSheet.ts +74 -0
- package/src/client/conversations/ConversationChildAgents.tsx +87 -58
- package/src/client/conversations/ConversationDetails.tsx +85 -67
- package/src/client/conversations/ConversationDetailsFrame.tsx +47 -19
- package/src/client/conversations/ConversationMeta.tsx +56 -4
- package/src/client/conversations/ConversationPage.tsx +28 -16
- package/src/client/conversations/ConversationUsageBreakdown.tsx +16 -3
- package/src/client/conversations/README.md +6 -5
- package/src/client/conversations/ShareConversationButton.tsx +15 -2
- package/src/client/conversations/TranscriptSubagentView.tsx +3 -3
- package/src/client/conversations/eventTranscript.ts +3 -0
- package/src/client/format.ts +3 -0
- package/src/client/lib/utils.ts +1 -0
- package/src/client/pages/dev/ComponentsPage.tsx +1 -1
- package/src/client/types.ts +2 -0
- package/src/mock-reporting/fixtures.ts +4 -0
- package/src/tailwind.css +77 -0
- package/src/client/components/Sheet.tsx +0 -141
- /package/src/client/components/{Sheet.LICENSE → ui/sheet.LICENSE} +0 -0
package/src/client/types.ts
CHANGED
|
@@ -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;
|
|
File without changes
|