@getcatalystiq/agent-plane-ui 0.1.30 → 0.1.31

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/index.js CHANGED
@@ -1,16 +1,76 @@
1
1
  import { Card, CardHeader, CardTitle, CardContent, useApi, Skeleton, FileTreeEditor } from './chunk-CE2RHDPY.js';
2
2
  export { Card, CardContent, CardDescription, CardHeader, CardTitle, Skeleton, useApi } from './chunk-CE2RHDPY.js';
3
- import { cn, Dialog, DialogContent, DialogHeader, DialogTitle, DialogBody, DialogFooter, Button, Badge, useNavigation, useAgentPlaneClient, DialogDescription, FormField, Input, supportsClaudeRunner, buttonVariants } from './chunk-XFI227OB.js';
3
+ import { cn, useAgentPlaneClient, Dialog, DialogContent, DialogHeader, DialogTitle, DialogBody, DialogFooter, Button, Badge, useNavigation, DialogDescription, FormField, Input, supportsClaudeRunner, buttonVariants } from './chunk-XFI227OB.js';
4
4
  export { AgentPlaneProvider, Badge, Button, Dialog, DialogBody, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, FormField, Input, badgeVariants, buttonVariants, cn, useAgentPlaneClient, useAuthError, useNavigation } from './chunk-XFI227OB.js';
5
+ import * as React4 from 'react';
6
+ import React4__default, { lazy, useState, useRef, useCallback, useEffect, useMemo, Suspense } from 'react';
5
7
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
6
- import * as React from 'react';
7
- import React__default, { lazy, useState, useCallback, useMemo, useRef, useEffect, Suspense } from 'react';
8
8
  import { useSWRConfig } from 'swr';
9
9
  import ReactMarkdown from 'react-markdown';
10
10
  import { Command } from 'cmdk';
11
11
  import * as Popover from '@radix-ui/react-popover';
12
12
  import remarkGfm from 'remark-gfm';
13
+ import * as ToastPrimitives from '@radix-ui/react-toast';
14
+ import { cva } from 'class-variance-authority';
13
15
 
16
+ var ACTIVE_STATUSES = /* @__PURE__ */ new Set(["running", "pending"]);
17
+ function useRunStream(runId, status) {
18
+ const client = useAgentPlaneClient();
19
+ const [events, setEvents] = useState([]);
20
+ const [isStreaming, setIsStreaming] = useState(false);
21
+ const [terminalEvent, setTerminalEvent] = useState(null);
22
+ const [streamingText, setStreamingText] = useState("");
23
+ const [error, setError] = useState(null);
24
+ const abortRef = useRef(null);
25
+ const startStream = useCallback(async (id, signal) => {
26
+ setIsStreaming(true);
27
+ setError(null);
28
+ try {
29
+ const stream = await client.runs.stream(id, { signal });
30
+ for await (const event of stream) {
31
+ if (signal.aborted) break;
32
+ if (event.type === "text_delta") {
33
+ const text = event.text ?? "";
34
+ setStreamingText((prev) => prev + text);
35
+ continue;
36
+ }
37
+ if (event.type === "assistant") {
38
+ setStreamingText("");
39
+ }
40
+ if (event.type === "stream_detached") {
41
+ continue;
42
+ }
43
+ setEvents((prev) => [...prev, event]);
44
+ if (event.type === "result" || event.type === "error") {
45
+ setTerminalEvent(event);
46
+ setIsStreaming(false);
47
+ setStreamingText("");
48
+ return;
49
+ }
50
+ }
51
+ setIsStreaming(false);
52
+ } catch (err) {
53
+ if (signal.aborted) return;
54
+ setError(err instanceof Error ? err : new Error(String(err)));
55
+ setIsStreaming(false);
56
+ }
57
+ }, [client]);
58
+ useEffect(() => {
59
+ if (!runId || !ACTIVE_STATUSES.has(status)) {
60
+ setIsStreaming(false);
61
+ return;
62
+ }
63
+ if (terminalEvent) return;
64
+ const controller = new AbortController();
65
+ abortRef.current = controller;
66
+ startStream(runId, controller.signal);
67
+ return () => {
68
+ controller.abort();
69
+ abortRef.current = null;
70
+ };
71
+ }, [runId, status, startStream, terminalEvent]);
72
+ return { events, isStreaming, terminalEvent, streamingText, error };
73
+ }
14
74
  function Select({ className = "", ...props }) {
15
75
  return /* @__PURE__ */ jsxs("div", { className: "relative w-full", children: [
16
76
  /* @__PURE__ */ jsx(
@@ -27,7 +87,7 @@ function Select({ className = "", ...props }) {
27
87
  ] }) })
28
88
  ] });
29
89
  }
30
- var Textarea = React.forwardRef(
90
+ var Textarea = React4.forwardRef(
31
91
  ({ className, ...props }, ref) => {
32
92
  return /* @__PURE__ */ jsx(
33
93
  "textarea",
@@ -133,7 +193,7 @@ function PaginationBar({
133
193
  return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-3 py-2 border-t border-border bg-muted/20 text-sm", children: [
134
194
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-muted-foreground", children: [
135
195
  /* @__PURE__ */ jsx("span", { children: "Rows per page:" }),
136
- PAGE_SIZE_OPTIONS.map((ps) => /* @__PURE__ */ jsx(React__default.Fragment, { children: renderLink(
196
+ PAGE_SIZE_OPTIONS.map((ps) => /* @__PURE__ */ jsx(React4__default.Fragment, { children: renderLink(
137
197
  buildHref(1, ps),
138
198
  ps,
139
199
  `px-2 py-0.5 rounded text-xs ${pageSize === ps ? "bg-primary text-primary-foreground font-medium" : "hover:bg-muted"}`
@@ -299,6 +359,102 @@ function DashboardPage({ initialData, chartComponent: ChartComponent }) {
299
359
  ChartComponent && /* @__PURE__ */ jsx(ChartComponent, { stats: daily_stats })
300
360
  ] });
301
361
  }
362
+ var TOAST_LIMIT = 5;
363
+ var TOAST_REMOVE_DELAY = 1e6;
364
+ var count = 0;
365
+ function genId() {
366
+ count = (count + 1) % Number.MAX_SAFE_INTEGER;
367
+ return count.toString();
368
+ }
369
+ var toastTimeouts = /* @__PURE__ */ new Map();
370
+ function addToRemoveQueue(toastId) {
371
+ if (toastTimeouts.has(toastId)) return;
372
+ const timeout = setTimeout(() => {
373
+ toastTimeouts.delete(toastId);
374
+ dispatch({ type: "REMOVE_TOAST", toastId });
375
+ }, TOAST_REMOVE_DELAY);
376
+ toastTimeouts.set(toastId, timeout);
377
+ }
378
+ function reducer(state, action) {
379
+ switch (action.type) {
380
+ case "ADD_TOAST":
381
+ return {
382
+ ...state,
383
+ toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT)
384
+ };
385
+ case "UPDATE_TOAST":
386
+ return {
387
+ ...state,
388
+ toasts: state.toasts.map(
389
+ (t) => t.id === action.toast.id ? { ...t, ...action.toast } : t
390
+ )
391
+ };
392
+ case "DISMISS_TOAST": {
393
+ const { toastId } = action;
394
+ if (toastId) {
395
+ addToRemoveQueue(toastId);
396
+ } else {
397
+ state.toasts.forEach((t) => addToRemoveQueue(t.id));
398
+ }
399
+ return {
400
+ ...state,
401
+ toasts: state.toasts.map(
402
+ (t) => t.id === toastId || toastId === void 0 ? { ...t, open: false } : t
403
+ )
404
+ };
405
+ }
406
+ case "REMOVE_TOAST":
407
+ if (action.toastId === void 0) {
408
+ return { ...state, toasts: [] };
409
+ }
410
+ return {
411
+ ...state,
412
+ toasts: state.toasts.filter((t) => t.id !== action.toastId)
413
+ };
414
+ }
415
+ }
416
+ var listeners = [];
417
+ var memoryState = { toasts: [] };
418
+ function dispatch(action) {
419
+ memoryState = reducer(memoryState, action);
420
+ listeners.forEach((listener) => listener(memoryState));
421
+ }
422
+ function toast(props) {
423
+ const id = genId();
424
+ const update = (updateProps) => dispatch({ type: "UPDATE_TOAST", toast: { ...updateProps, id } });
425
+ const dismiss2 = () => dispatch({ type: "DISMISS_TOAST", toastId: id });
426
+ dispatch({
427
+ type: "ADD_TOAST",
428
+ toast: {
429
+ ...props,
430
+ id,
431
+ open: true,
432
+ onOpenChange: (open) => {
433
+ if (!open) dismiss2();
434
+ }
435
+ }
436
+ });
437
+ return { id, dismiss: dismiss2, update };
438
+ }
439
+ function dismiss(toastId) {
440
+ const action = toastId !== void 0 ? { type: "DISMISS_TOAST", toastId } : { type: "DISMISS_TOAST" };
441
+ dispatch(action);
442
+ }
443
+ function useToast() {
444
+ const [state, setState] = React4.useState(memoryState);
445
+ React4.useEffect(() => {
446
+ listeners.push(setState);
447
+ return () => {
448
+ const index = listeners.indexOf(setState);
449
+ if (index > -1) listeners.splice(index, 1);
450
+ };
451
+ }, [state]);
452
+ return {
453
+ ...state,
454
+ toast,
455
+ dismiss
456
+ };
457
+ }
302
458
  var SOURCES = [
303
459
  { value: "", label: "All Sources" },
304
460
  { value: "api", label: "API" },
@@ -308,11 +464,18 @@ var SOURCES = [
308
464
  { value: "a2a", label: "A2A" }
309
465
  ];
310
466
  var VALID_SOURCES = SOURCES.filter((s) => s.value).map((s) => s.value);
467
+ var ACTIVE_STATUSES2 = /* @__PURE__ */ new Set(["running", "pending"]);
468
+ var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled", "timed_out"]);
311
469
  function RunListPage({ initialData }) {
312
470
  const { LinkComponent, basePath } = useNavigation();
471
+ const { toast: toast2 } = useToast();
313
472
  const [page, setPage] = useState(1);
314
473
  const [pageSize, setPageSize] = useState(20);
315
474
  const [sourceFilter, setSourceFilter] = useState(null);
475
+ const prevStatusesRef = useRef(/* @__PURE__ */ new Map());
476
+ const [activeRunsExist, setActiveRunsExist] = useState(
477
+ () => initialData?.data?.some((r) => ACTIVE_STATUSES2.has(r.status)) ?? false
478
+ );
316
479
  const cacheKey = `runs-${page}-${pageSize}-${sourceFilter || "all"}`;
317
480
  const { data, error, isLoading } = useApi(
318
481
  cacheKey,
@@ -323,8 +486,29 @@ function RunListPage({ initialData }) {
323
486
  ...sourceFilter ? { triggered_by: sourceFilter } : {}
324
487
  });
325
488
  },
326
- initialData ? { fallbackData: initialData } : void 0
489
+ {
490
+ ...initialData ? { fallbackData: initialData } : {},
491
+ refreshInterval: activeRunsExist ? 5e3 : 0
492
+ }
327
493
  );
494
+ useEffect(() => {
495
+ if (!data?.data) return;
496
+ const prev = prevStatusesRef.current;
497
+ const next = /* @__PURE__ */ new Map();
498
+ for (const run of data.data) {
499
+ next.set(run.id, run.status);
500
+ const oldStatus = prev.get(run.id);
501
+ if (oldStatus && ACTIVE_STATUSES2.has(oldStatus) && TERMINAL_STATUSES.has(run.status)) {
502
+ toast2({
503
+ title: `Run ${run.status}`,
504
+ description: run.agent_name,
505
+ variant: run.status === "completed" ? "success" : "destructive"
506
+ });
507
+ }
508
+ }
509
+ prevStatusesRef.current = next;
510
+ setActiveRunsExist(data.data.some((r) => ACTIVE_STATUSES2.has(r.status)));
511
+ }, [data, toast2]);
328
512
  const handleSourceChange = useCallback((e) => {
329
513
  const value = e.target.value;
330
514
  setSourceFilter(VALID_SOURCES.includes(value) ? value : null);
@@ -505,17 +689,51 @@ function buildConversation(events) {
505
689
  }
506
690
  return items;
507
691
  }
508
- function TranscriptViewer({ transcript, prompt }) {
692
+ function TranscriptViewer({ transcript, prompt, isStreaming = false }) {
509
693
  const conversation = useMemo(() => buildConversation(transcript), [transcript]);
694
+ const scrollContainerRef = useRef(null);
695
+ const sentinelRef = useRef(null);
696
+ const userHasScrolledUpRef = useRef(false);
697
+ const [userHasScrolledUp, setUserHasScrolledUp] = useState(false);
698
+ const handleScroll = useCallback(() => {
699
+ const el = scrollContainerRef.current;
700
+ if (!el) return;
701
+ const atBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 50;
702
+ if (atBottom) {
703
+ userHasScrolledUpRef.current = false;
704
+ setUserHasScrolledUp(false);
705
+ } else {
706
+ userHasScrolledUpRef.current = true;
707
+ setUserHasScrolledUp(true);
708
+ }
709
+ }, []);
710
+ useEffect(() => {
711
+ if (isStreaming && !userHasScrolledUpRef.current) {
712
+ sentinelRef.current?.scrollIntoView({ behavior: "smooth" });
713
+ }
714
+ }, [transcript.length, isStreaming]);
510
715
  return /* @__PURE__ */ jsxs(Card, { children: [
511
716
  /* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsx(CardTitle, { className: "text-base", children: "Transcript" }) }),
512
- /* @__PURE__ */ jsxs(CardContent, { className: "space-y-3", children: [
513
- prompt && /* @__PURE__ */ jsxs("div", { className: "rounded-md border border-border bg-muted/20 px-4 py-3", children: [
514
- /* @__PURE__ */ jsx("div", { className: "text-xs font-medium text-muted-foreground mb-1", children: "Prompt" }),
515
- /* @__PURE__ */ jsx("pre", { className: "text-xs font-mono whitespace-pre-wrap", children: prompt })
516
- ] }),
517
- transcript.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "No transcript available" }) : /* @__PURE__ */ jsx(ConversationView, { items: conversation })
518
- ] })
717
+ /* @__PURE__ */ jsx(CardContent, { className: "p-0", children: /* @__PURE__ */ jsxs(
718
+ "div",
719
+ {
720
+ ref: scrollContainerRef,
721
+ onScroll: isStreaming ? handleScroll : void 0,
722
+ className: "space-y-3 overflow-y-auto px-6 pb-6",
723
+ children: [
724
+ prompt && /* @__PURE__ */ jsxs("div", { className: "rounded-md border border-border bg-muted/20 px-4 py-3", children: [
725
+ /* @__PURE__ */ jsx("div", { className: "text-xs font-medium text-muted-foreground mb-1", children: "Prompt" }),
726
+ /* @__PURE__ */ jsx("pre", { className: "text-xs font-mono whitespace-pre-wrap", children: prompt })
727
+ ] }),
728
+ transcript.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "No transcript available" }) : /* @__PURE__ */ jsx(ConversationView, { items: conversation }),
729
+ isStreaming && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-4 py-2 text-xs text-muted-foreground", children: [
730
+ /* @__PURE__ */ jsx("span", { className: "h-2 w-2 rounded-full bg-blue-400 animate-pulse" }),
731
+ "Streaming..."
732
+ ] }),
733
+ /* @__PURE__ */ jsx("div", { ref: sentinelRef })
734
+ ]
735
+ }
736
+ ) })
519
737
  ] });
520
738
  }
521
739
  function ConversationView({ items }) {
@@ -669,6 +887,7 @@ function ErrorItem({ item }) {
669
887
  }
670
888
  function RunDetailPage({ runId, initialData, initialTranscript }) {
671
889
  const { mutate } = useSWRConfig();
890
+ const { toast: toast2 } = useToast();
672
891
  const { data: run, error, isLoading } = useApi(
673
892
  `run-${runId}`,
674
893
  (client) => client.runs.get(runId),
@@ -679,6 +898,20 @@ function RunDetailPage({ runId, initialData, initialTranscript }) {
679
898
  (client) => client.runs.transcriptArray(runId),
680
899
  initialTranscript ? { fallbackData: initialTranscript } : void 0
681
900
  );
901
+ const isActive = run?.status === "running" || run?.status === "pending";
902
+ const { events, isStreaming, terminalEvent, streamingText } = useRunStream(
903
+ runId,
904
+ run?.status ?? ""
905
+ );
906
+ useEffect(() => {
907
+ if (!terminalEvent) return;
908
+ toast2({
909
+ title: terminalEvent.type === "result" ? "Run completed" : "Run failed",
910
+ variant: terminalEvent.type === "result" ? "success" : "destructive"
911
+ });
912
+ mutate(`run-${runId}`);
913
+ mutate(`transcript-${runId}`);
914
+ }, [terminalEvent, toast2, mutate, runId]);
682
915
  if (error) {
683
916
  return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center min-h-[40vh]", children: /* @__PURE__ */ jsxs("p", { className: "text-destructive", children: [
684
917
  "Failed to load run: ",
@@ -711,16 +944,26 @@ function RunDetailPage({ runId, initialData, initialTranscript }) {
711
944
  ] }),
712
945
  /* @__PURE__ */ jsx(MetricCard, { label: "Cost", children: /* @__PURE__ */ jsxs("span", { className: "font-mono", children: [
713
946
  "$",
714
- run.cost_usd != null ? run.cost_usd.toFixed(4) : "\u2014"
947
+ (() => {
948
+ const cost = terminalEvent?.cost_usd ?? run.cost_usd;
949
+ return cost != null ? Number(cost).toFixed(4) : "\u2014";
950
+ })()
715
951
  ] }) }),
716
- /* @__PURE__ */ jsx(MetricCard, { label: "Turns", children: run.num_turns }),
717
- /* @__PURE__ */ jsx(MetricCard, { label: "Duration", children: run.duration_ms > 0 ? `${(run.duration_ms / 1e3).toFixed(1)}s` : "\u2014" }),
952
+ /* @__PURE__ */ jsx(MetricCard, { label: "Turns", children: terminalEvent?.num_turns ?? run.num_turns }),
953
+ /* @__PURE__ */ jsx(MetricCard, { label: "Duration", children: (() => {
954
+ const ms = terminalEvent?.duration_ms ?? run.duration_ms;
955
+ return ms > 0 ? `${(ms / 1e3).toFixed(1)}s` : "\u2014";
956
+ })() }),
718
957
  /* @__PURE__ */ jsxs(MetricCard, { label: "Tokens", children: [
719
- (run.total_input_tokens + run.total_output_tokens).toLocaleString(),
958
+ (() => {
959
+ const inTok = terminalEvent?.total_input_tokens ?? run.total_input_tokens;
960
+ const outTok = terminalEvent?.total_output_tokens ?? run.total_output_tokens;
961
+ return (inTok + outTok).toLocaleString();
962
+ })(),
720
963
  /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground mt-0.5 font-normal", children: [
721
- run.total_input_tokens.toLocaleString(),
964
+ (terminalEvent?.total_input_tokens ?? run.total_input_tokens).toLocaleString(),
722
965
  " in / ",
723
- run.total_output_tokens.toLocaleString(),
966
+ (terminalEvent?.total_output_tokens ?? run.total_output_tokens).toLocaleString(),
724
967
  " out"
725
968
  ] })
726
969
  ] })
@@ -732,7 +975,18 @@ function RunDetailPage({ runId, initialData, initialTranscript }) {
732
975
  run.error_messages.map((msg, i) => /* @__PURE__ */ jsx("pre", { className: "whitespace-pre-wrap text-sm text-destructive font-mono bg-destructive/10 rounded-md p-3", children: msg }, i))
733
976
  ] })
734
977
  ] }),
735
- /* @__PURE__ */ jsx(TranscriptViewer, { transcript: transcript || [], prompt: run.prompt }),
978
+ /* @__PURE__ */ jsx(
979
+ TranscriptViewer,
980
+ {
981
+ transcript: isActive && isStreaming ? events : transcript || [],
982
+ prompt: run.prompt,
983
+ isStreaming: isActive && isStreaming
984
+ }
985
+ ),
986
+ isActive && streamingText && /* @__PURE__ */ jsx("div", { className: "rounded-lg border bg-muted/30 p-4", children: /* @__PURE__ */ jsxs("pre", { className: "whitespace-pre-wrap text-sm font-mono", children: [
987
+ streamingText,
988
+ /* @__PURE__ */ jsx("span", { className: "inline-block w-2 h-4 ml-0.5 bg-foreground/70 animate-pulse align-text-bottom" })
989
+ ] }) }),
736
990
  /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsxs("details", { children: [
737
991
  /* @__PURE__ */ jsxs("summary", { className: "flex items-center justify-between px-6 py-4 cursor-pointer list-none hover:bg-muted/30 transition-colors rounded-xl", children: [
738
992
  /* @__PURE__ */ jsx("span", { className: "text-base font-semibold", children: "Metadata" }),
@@ -4693,7 +4947,7 @@ function renderEvent(event, idx) {
4693
4947
  /* @__PURE__ */ jsx(CollapsibleJson, { data: event, maxHeight: "8rem" })
4694
4948
  ] }, idx);
4695
4949
  }
4696
- var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled", "timed_out"]);
4950
+ var TERMINAL_STATUSES2 = /* @__PURE__ */ new Set(["completed", "failed", "cancelled", "timed_out"]);
4697
4951
  function PlaygroundPage({ agentId }) {
4698
4952
  const client = useAgentPlaneClient();
4699
4953
  const { LinkComponent, basePath } = useNavigation();
@@ -4735,7 +4989,7 @@ function PlaygroundPage({ agentId }) {
4735
4989
  if (abortRef.current?.signal.aborted) break;
4736
4990
  try {
4737
4991
  const run = await client.runs.get(runId);
4738
- if (TERMINAL_STATUSES.has(run.status)) {
4992
+ if (TERMINAL_STATUSES2.has(run.status)) {
4739
4993
  try {
4740
4994
  const transcriptEvents = await client.runs.transcriptArray(runId);
4741
4995
  if (transcriptEvents.length > 0) {
@@ -4971,5 +5225,121 @@ function PlaygroundPage({ agentId }) {
4971
5225
  ] })
4972
5226
  ] });
4973
5227
  }
5228
+ var ToastProvider = ToastPrimitives.Provider;
5229
+ var ToastViewport = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
5230
+ ToastPrimitives.Viewport,
5231
+ {
5232
+ ref,
5233
+ className: cn(
5234
+ "fixed top-0 right-0 z-[100] flex max-h-screen w-full flex-col-reverse gap-2 p-4 sm:flex-col sm:max-w-[420px]",
5235
+ className
5236
+ ),
5237
+ ...props
5238
+ }
5239
+ ));
5240
+ ToastViewport.displayName = ToastPrimitives.Viewport.displayName;
5241
+ var toastVariants = cva(
5242
+ "group pointer-events-auto relative flex w-full items-center justify-between gap-4 overflow-hidden rounded-lg border p-4 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-right-full",
5243
+ {
5244
+ variants: {
5245
+ variant: {
5246
+ default: "bg-zinc-800 border-zinc-700 text-zinc-100",
5247
+ success: "bg-green-950 border-green-900 text-green-400",
5248
+ destructive: "bg-red-950 border-red-900 text-red-400"
5249
+ }
5250
+ },
5251
+ defaultVariants: {
5252
+ variant: "default"
5253
+ }
5254
+ }
5255
+ );
5256
+ var Toast = React4.forwardRef(({ className, variant, ...props }, ref) => /* @__PURE__ */ jsx(
5257
+ ToastPrimitives.Root,
5258
+ {
5259
+ ref,
5260
+ className: cn(toastVariants({ variant }), className),
5261
+ ...props
5262
+ }
5263
+ ));
5264
+ Toast.displayName = ToastPrimitives.Root.displayName;
5265
+ var ToastAction = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
5266
+ ToastPrimitives.Action,
5267
+ {
5268
+ ref,
5269
+ className: cn(
5270
+ "inline-flex h-8 shrink-0 items-center justify-center rounded-md border border-zinc-600 bg-transparent px-3 text-sm font-medium transition-colors hover:bg-zinc-700 focus:outline-none focus:ring-1 focus:ring-zinc-500 disabled:pointer-events-none disabled:opacity-50",
5271
+ "group-[.destructive]:border-red-800 group-[.destructive]:hover:border-red-700 group-[.destructive]:hover:bg-red-900 group-[.destructive]:focus:ring-red-800",
5272
+ "group-[.success]:border-green-800 group-[.success]:hover:border-green-700 group-[.success]:hover:bg-green-900 group-[.success]:focus:ring-green-800",
5273
+ className
5274
+ ),
5275
+ ...props
5276
+ }
5277
+ ));
5278
+ ToastAction.displayName = ToastPrimitives.Action.displayName;
5279
+ var ToastClose = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
5280
+ ToastPrimitives.Close,
5281
+ {
5282
+ ref,
5283
+ className: cn(
5284
+ "absolute right-1 top-1 rounded-md p-1 text-zinc-400 opacity-0 transition-opacity hover:text-zinc-100 focus:opacity-100 focus:outline-none group-hover:opacity-100",
5285
+ "group-[.destructive]:text-red-400 group-[.destructive]:hover:text-red-300",
5286
+ "group-[.success]:text-green-400 group-[.success]:hover:text-green-300",
5287
+ className
5288
+ ),
5289
+ "toast-close": "",
5290
+ ...props,
5291
+ children: /* @__PURE__ */ jsxs(
5292
+ "svg",
5293
+ {
5294
+ xmlns: "http://www.w3.org/2000/svg",
5295
+ width: "16",
5296
+ height: "16",
5297
+ viewBox: "0 0 24 24",
5298
+ fill: "none",
5299
+ stroke: "currentColor",
5300
+ strokeWidth: "2",
5301
+ strokeLinecap: "round",
5302
+ strokeLinejoin: "round",
5303
+ children: [
5304
+ /* @__PURE__ */ jsx("path", { d: "M18 6 6 18" }),
5305
+ /* @__PURE__ */ jsx("path", { d: "m6 6 12 12" })
5306
+ ]
5307
+ }
5308
+ )
5309
+ }
5310
+ ));
5311
+ ToastClose.displayName = ToastPrimitives.Close.displayName;
5312
+ var ToastTitle = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
5313
+ ToastPrimitives.Title,
5314
+ {
5315
+ ref,
5316
+ className: cn("text-sm font-semibold [&+div]:text-xs", className),
5317
+ ...props
5318
+ }
5319
+ ));
5320
+ ToastTitle.displayName = ToastPrimitives.Title.displayName;
5321
+ var ToastDescription = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
5322
+ ToastPrimitives.Description,
5323
+ {
5324
+ ref,
5325
+ className: cn("text-sm opacity-90", className),
5326
+ ...props
5327
+ }
5328
+ ));
5329
+ ToastDescription.displayName = ToastPrimitives.Description.displayName;
5330
+ function Toaster() {
5331
+ const { toasts } = useToast();
5332
+ return /* @__PURE__ */ jsxs(ToastProvider, { children: [
5333
+ toasts.map(({ id, title, description, action, ...props }) => /* @__PURE__ */ jsxs(Toast, { ...props, children: [
5334
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-1", children: [
5335
+ title && /* @__PURE__ */ jsx(ToastTitle, { children: title }),
5336
+ description && /* @__PURE__ */ jsx(ToastDescription, { children: description })
5337
+ ] }),
5338
+ action,
5339
+ /* @__PURE__ */ jsx(ToastClose, {})
5340
+ ] }, id)),
5341
+ /* @__PURE__ */ jsx(ToastViewport, {})
5342
+ ] });
5343
+ }
4974
5344
 
4975
- export { AdminTable, AdminTableHead, AdminTableRow, AgentA2aInfo, AgentConnectorsManager, AgentDetailPage, AgentEditForm, AgentListPage, AgentPluginManager, AgentRuns, AgentScheduleForm, AgentSkillManager, ConfirmDialog, CopyButton, DashboardPage, DetailPageHeader, EmptyRow, FormError, LocalDate, McpServerListPage, MetricCard, ModelSelector, PaginationBar, PlaygroundPage, PluginDetailPage, PluginMarketplaceDetailPage, PluginMarketplaceListPage, RunDetailPage, RunListPage, RunSourceBadge, RunStatusBadge, SectionHeader, Select, SettingsPage, Tabs, Textarea, Th, ToolkitMultiselect, TranscriptViewer, parsePaginationParams };
5345
+ export { AdminTable, AdminTableHead, AdminTableRow, AgentA2aInfo, AgentConnectorsManager, AgentDetailPage, AgentEditForm, AgentListPage, AgentPluginManager, AgentRuns, AgentScheduleForm, AgentSkillManager, ConfirmDialog, CopyButton, DashboardPage, DetailPageHeader, EmptyRow, FormError, LocalDate, McpServerListPage, MetricCard, ModelSelector, PaginationBar, PlaygroundPage, PluginDetailPage, PluginMarketplaceDetailPage, PluginMarketplaceListPage, RunDetailPage, RunListPage, RunSourceBadge, RunStatusBadge, SectionHeader, Select, SettingsPage, Tabs, Textarea, Th, Toast, ToastAction, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport, Toaster, ToolkitMultiselect, TranscriptViewer, parsePaginationParams, toast, toastVariants, useRunStream, useToast };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getcatalystiq/agent-plane-ui",
3
- "version": "0.1.30",
3
+ "version": "0.1.31",
4
4
  "description": "Embeddable React component library for AgentPlane",
5
5
  "type": "module",
6
6
  "exports": {
@@ -92,6 +92,7 @@
92
92
  },
93
93
  "dependencies": {
94
94
  "@radix-ui/react-popover": "^1.0.0",
95
+ "@radix-ui/react-toast": "^1.2.15",
95
96
  "class-variance-authority": "^0.7.0",
96
97
  "clsx": "^2.0.0",
97
98
  "cmdk": "^1.0.0",