@epicbagel/saas-kit 1.21.0 → 1.22.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.
@@ -8,14 +8,14 @@ import '@radix-ui/react-separator';
8
8
  declare function ItemGroup({ className, ...props }: React.ComponentProps<"div">): react_jsx_runtime.JSX.Element;
9
9
  declare function ItemSeparator({ className, ...props }: React.ComponentProps<typeof Separator>): react_jsx_runtime.JSX.Element;
10
10
  declare const itemVariants: (props?: ({
11
- variant?: "default" | "muted" | "outline" | null | undefined;
11
+ variant?: "muted" | "default" | "outline" | null | undefined;
12
12
  size?: "xs" | "sm" | "default" | null | undefined;
13
13
  } & class_variance_authority_types.ClassProp) | undefined) => string;
14
14
  declare function Item({ className, variant, size, asChild, ...props }: React.ComponentProps<"div"> & VariantProps<typeof itemVariants> & {
15
15
  asChild?: boolean;
16
16
  }): react_jsx_runtime.JSX.Element;
17
17
  declare const itemMediaVariants: (props?: ({
18
- variant?: "image" | "default" | "icon" | null | undefined;
18
+ variant?: "icon" | "image" | "default" | null | undefined;
19
19
  } & class_variance_authority_types.ClassProp) | undefined) => string;
20
20
  declare function ItemMedia({ className, variant, ...props }: React.ComponentProps<"div"> & VariantProps<typeof itemMediaVariants>): react_jsx_runtime.JSX.Element;
21
21
  declare function ItemContent({ className, ...props }: React.ComponentProps<"div">): react_jsx_runtime.JSX.Element;
@@ -8,14 +8,14 @@ import '@radix-ui/react-separator';
8
8
  declare function ItemGroup({ className, ...props }: React.ComponentProps<"div">): react_jsx_runtime.JSX.Element;
9
9
  declare function ItemSeparator({ className, ...props }: React.ComponentProps<typeof Separator>): react_jsx_runtime.JSX.Element;
10
10
  declare const itemVariants: (props?: ({
11
- variant?: "default" | "muted" | "outline" | null | undefined;
11
+ variant?: "muted" | "default" | "outline" | null | undefined;
12
12
  size?: "xs" | "sm" | "default" | null | undefined;
13
13
  } & class_variance_authority_types.ClassProp) | undefined) => string;
14
14
  declare function Item({ className, variant, size, asChild, ...props }: React.ComponentProps<"div"> & VariantProps<typeof itemVariants> & {
15
15
  asChild?: boolean;
16
16
  }): react_jsx_runtime.JSX.Element;
17
17
  declare const itemMediaVariants: (props?: ({
18
- variant?: "image" | "default" | "icon" | null | undefined;
18
+ variant?: "icon" | "image" | "default" | null | undefined;
19
19
  } & class_variance_authority_types.ClassProp) | undefined) => string;
20
20
  declare function ItemMedia({ className, variant, ...props }: React.ComponentProps<"div"> & VariantProps<typeof itemMediaVariants>): react_jsx_runtime.JSX.Element;
21
21
  declare function ItemContent({ className, ...props }: React.ComponentProps<"div">): react_jsx_runtime.JSX.Element;
@@ -5,7 +5,7 @@ import { VariantProps } from 'class-variance-authority';
5
5
 
6
6
  declare const sectionHeaderVariants: (props?: ({
7
7
  variant?: "muted" | "plain" | null | undefined;
8
- spacing?: "none" | "tight" | "loose" | null | undefined;
8
+ spacing?: "tight" | "loose" | "none" | null | undefined;
9
9
  } & class_variance_authority_types.ClassProp) | undefined) => string;
10
10
  interface SectionHeaderProps extends Omit<HTMLAttributes<HTMLHeadingElement>, "children">, VariantProps<typeof sectionHeaderVariants> {
11
11
  /** Pre-rendered icon node. Sized to match the header text. */
@@ -5,7 +5,7 @@ import { VariantProps } from 'class-variance-authority';
5
5
 
6
6
  declare const sectionHeaderVariants: (props?: ({
7
7
  variant?: "muted" | "plain" | null | undefined;
8
- spacing?: "none" | "tight" | "loose" | null | undefined;
8
+ spacing?: "tight" | "loose" | "none" | null | undefined;
9
9
  } & class_variance_authority_types.ClassProp) | undefined) => string;
10
10
  interface SectionHeaderProps extends Omit<HTMLAttributes<HTMLHeadingElement>, "children">, VariantProps<typeof sectionHeaderVariants> {
11
11
  /** Pre-rendered icon node. Sized to match the header text. */
@@ -5,11 +5,11 @@ import { VariantProps } from 'class-variance-authority';
5
5
 
6
6
  declare const ToggleGroup: React.ForwardRefExoticComponent<((Omit<ToggleGroupPrimitive.ToggleGroupSingleProps & React.RefAttributes<HTMLDivElement>, "ref"> | Omit<ToggleGroupPrimitive.ToggleGroupMultipleProps & React.RefAttributes<HTMLDivElement>, "ref">) & VariantProps<(props?: ({
7
7
  variant?: "default" | "outline" | null | undefined;
8
- size?: "sm" | "lg" | "default" | "icon" | "icon-lg" | "avatar" | "chip" | null | undefined;
8
+ size?: "icon" | "sm" | "lg" | "default" | "icon-lg" | "avatar" | "chip" | null | undefined;
9
9
  } & class_variance_authority_types.ClassProp) | undefined) => string>) & React.RefAttributes<HTMLDivElement>>;
10
10
  declare const ToggleGroupItem: React.ForwardRefExoticComponent<Omit<ToggleGroupPrimitive.ToggleGroupItemProps & React.RefAttributes<HTMLButtonElement>, "ref"> & VariantProps<(props?: ({
11
11
  variant?: "default" | "outline" | null | undefined;
12
- size?: "sm" | "lg" | "default" | "icon" | "icon-lg" | "avatar" | "chip" | null | undefined;
12
+ size?: "icon" | "sm" | "lg" | "default" | "icon-lg" | "avatar" | "chip" | null | undefined;
13
13
  } & class_variance_authority_types.ClassProp) | undefined) => string> & {
14
14
  grow?: boolean;
15
15
  textSize?: "inherit" | "xs";
@@ -5,11 +5,11 @@ import { VariantProps } from 'class-variance-authority';
5
5
 
6
6
  declare const ToggleGroup: React.ForwardRefExoticComponent<((Omit<ToggleGroupPrimitive.ToggleGroupSingleProps & React.RefAttributes<HTMLDivElement>, "ref"> | Omit<ToggleGroupPrimitive.ToggleGroupMultipleProps & React.RefAttributes<HTMLDivElement>, "ref">) & VariantProps<(props?: ({
7
7
  variant?: "default" | "outline" | null | undefined;
8
- size?: "sm" | "lg" | "default" | "icon" | "icon-lg" | "avatar" | "chip" | null | undefined;
8
+ size?: "icon" | "sm" | "lg" | "default" | "icon-lg" | "avatar" | "chip" | null | undefined;
9
9
  } & class_variance_authority_types.ClassProp) | undefined) => string>) & React.RefAttributes<HTMLDivElement>>;
10
10
  declare const ToggleGroupItem: React.ForwardRefExoticComponent<Omit<ToggleGroupPrimitive.ToggleGroupItemProps & React.RefAttributes<HTMLButtonElement>, "ref"> & VariantProps<(props?: ({
11
11
  variant?: "default" | "outline" | null | undefined;
12
- size?: "sm" | "lg" | "default" | "icon" | "icon-lg" | "avatar" | "chip" | null | undefined;
12
+ size?: "icon" | "sm" | "lg" | "default" | "icon-lg" | "avatar" | "chip" | null | undefined;
13
13
  } & class_variance_authority_types.ClassProp) | undefined) => string> & {
14
14
  grow?: boolean;
15
15
  textSize?: "inherit" | "xs";
@@ -5,11 +5,11 @@ import * as React from 'react';
5
5
 
6
6
  declare const toggleVariants: (props?: ({
7
7
  variant?: "default" | "outline" | null | undefined;
8
- size?: "sm" | "lg" | "default" | "icon" | "icon-lg" | "avatar" | "chip" | null | undefined;
8
+ size?: "icon" | "sm" | "lg" | "default" | "icon-lg" | "avatar" | "chip" | null | undefined;
9
9
  } & class_variance_authority_types.ClassProp) | undefined) => string;
10
10
  declare const Toggle: React.ForwardRefExoticComponent<Omit<TogglePrimitive.ToggleProps & React.RefAttributes<HTMLButtonElement>, "ref"> & VariantProps<(props?: ({
11
11
  variant?: "default" | "outline" | null | undefined;
12
- size?: "sm" | "lg" | "default" | "icon" | "icon-lg" | "avatar" | "chip" | null | undefined;
12
+ size?: "icon" | "sm" | "lg" | "default" | "icon-lg" | "avatar" | "chip" | null | undefined;
13
13
  } & class_variance_authority_types.ClassProp) | undefined) => string> & React.RefAttributes<HTMLButtonElement>>;
14
14
 
15
15
  export { Toggle, toggleVariants };
@@ -5,11 +5,11 @@ import * as React from 'react';
5
5
 
6
6
  declare const toggleVariants: (props?: ({
7
7
  variant?: "default" | "outline" | null | undefined;
8
- size?: "sm" | "lg" | "default" | "icon" | "icon-lg" | "avatar" | "chip" | null | undefined;
8
+ size?: "icon" | "sm" | "lg" | "default" | "icon-lg" | "avatar" | "chip" | null | undefined;
9
9
  } & class_variance_authority_types.ClassProp) | undefined) => string;
10
10
  declare const Toggle: React.ForwardRefExoticComponent<Omit<TogglePrimitive.ToggleProps & React.RefAttributes<HTMLButtonElement>, "ref"> & VariantProps<(props?: ({
11
11
  variant?: "default" | "outline" | null | undefined;
12
- size?: "sm" | "lg" | "default" | "icon" | "icon-lg" | "avatar" | "chip" | null | undefined;
12
+ size?: "icon" | "sm" | "lg" | "default" | "icon-lg" | "avatar" | "chip" | null | undefined;
13
13
  } & class_variance_authority_types.ClassProp) | undefined) => string> & React.RefAttributes<HTMLButtonElement>>;
14
14
 
15
15
  export { Toggle, toggleVariants };
@@ -2,32 +2,7 @@
2
2
  "use client";
3
3
 
4
4
 
5
-
6
- var _chunk4YJ6DGPLcjs = require('../chunk-4YJ6DGPL.cjs');
7
- require('../chunk-2BTDBZYN.cjs');
8
- require('../chunk-PH2TV7XI.cjs');
9
- require('../chunk-YMI3X2YL.cjs');
10
- require('../chunk-M4V7OJNF.cjs');
11
- require('../chunk-B765DSRG.cjs');
12
- require('../chunk-23IETCLV.cjs');
13
- require('../chunk-DMPSKGFM.cjs');
14
- require('../chunk-NWDPH2Z7.cjs');
15
- require('../chunk-Z2H4LJVG.cjs');
16
- require('../chunk-7LDJAXRX.cjs');
17
- require('../chunk-2HV2KKOE.cjs');
18
- require('../chunk-ZLEM2SAU.cjs');
19
- require('../chunk-KENBU3NV.cjs');
20
- require('../chunk-ELPV44S6.cjs');
21
- require('../chunk-2BHI5ZWJ.cjs');
22
- require('../chunk-ZAITUDYD.cjs');
23
- require('../chunk-U2NES7VR.cjs');
24
- require('../chunk-V4YWTRLD.cjs');
25
- require('../chunk-373W6VAD.cjs');
26
- require('../chunk-W5HPHEE7.cjs');
27
- require('../chunk-FYRQFEU4.cjs');
28
- require('../chunk-2KFZQJH5.cjs');
29
- require('../chunk-PQUSJEXL.cjs');
30
- require('../chunk-WABCLRBR.cjs');
5
+ var _chunkYMI3X2YLcjs = require('../chunk-YMI3X2YL.cjs');
31
6
  require('../chunk-NKWHDI4C.cjs');
32
7
 
33
8
 
@@ -36,10 +11,6 @@ var _chunkJDEXZGIYcjs = require('../chunk-JDEXZGIY.cjs');
36
11
 
37
12
  var _chunkKWLSBTB2cjs = require('../chunk-KWLSBTB2.cjs');
38
13
  require('../chunk-2BSFYU22.cjs');
39
- require('../chunk-4LXN6GLZ.cjs');
40
- require('../chunk-7Q4EFCUI.cjs');
41
- require('../chunk-R35FT53G.cjs');
42
- require('../chunk-H2UFRLLN.cjs');
43
14
 
44
15
  // src/primitives/workflow-assistant.tsx
45
16
  var _react = require('react');
@@ -62,15 +33,11 @@ var WorkflowAssistant = _react.forwardRef.call(void 0, function WorkflowAssistan
62
33
  title = "Voice review",
63
34
  context,
64
35
  description,
65
- messages,
66
- value,
67
- onChange,
68
- onSend,
36
+ summaries,
69
37
  voiceSession,
70
38
  pending,
71
39
  disabled,
72
40
  error,
73
- placeholder = "Describe an action\u2026",
74
41
  besideCornerAction = false,
75
42
  labels,
76
43
  className
@@ -89,9 +56,10 @@ var WorkflowAssistant = _react.forwardRef.call(void 0, function WorkflowAssistan
89
56
  moveFocus.current = true;
90
57
  onOpenChange(next);
91
58
  };
92
- const startDisabled = pending || disabled || _optionalChain([voiceSession, 'optionalAccess', _3 => _3.disabled]);
93
- const active = voiceSession && voiceSession.state !== "disconnected" && voiceSession.state !== "error";
94
- const status = voiceSession && (voiceSession.muted && voiceSession.state === "listening" ? _nullishCoalesce(_optionalChain([voiceSession, 'access', _4 => _4.labels, 'optionalAccess', _5 => _5.muted]), () => ( "Microphone muted")) : _nullishCoalesce(_optionalChain([voiceSession, 'access', _6 => _6.labels, 'optionalAccess', _7 => _7[voiceSession.state]]), () => ( SESSION_LABELS[voiceSession.state])));
59
+ const startDisabled = pending || disabled || voiceSession.disabled;
60
+ const active = voiceSession.state !== "disconnected" && voiceSession.state !== "error";
61
+ const status = voiceSession.muted && voiceSession.state === "listening" ? _nullishCoalesce(_optionalChain([voiceSession, 'access', _3 => _3.labels, 'optionalAccess', _4 => _4.muted]), () => ( "Microphone muted")) : _nullishCoalesce(_optionalChain([voiceSession, 'access', _5 => _5.labels, 'optionalAccess', _6 => _6[voiceSession.state]]), () => ( SESSION_LABELS[voiceSession.state]));
62
+ const unavailable = voiceSession.state === "error" && voiceSession.disabled;
95
63
  if (!open) return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
96
64
  "aside",
97
65
  {
@@ -107,17 +75,17 @@ var WorkflowAssistant = _react.forwardRef.call(void 0, function WorkflowAssistan
107
75
  type: "button",
108
76
  shape: "pill",
109
77
  className: "min-h-12 min-w-12 max-w-full gap-2 shadow-lg",
110
- disabled: startDisabled && !active,
111
- "aria-label": active ? title : _nullishCoalesce(_optionalChain([labels, 'optionalAccess', _8 => _8.start]), () => ( "Start voice review")),
78
+ disabled: startDisabled && !active && !unavailable,
79
+ "aria-label": active ? title : unavailable ? "Voice review unavailable" : _nullishCoalesce(_optionalChain([labels, 'optionalAccess', _7 => _7.start]), () => ( "Start voice review")),
112
80
  "aria-expanded": false,
113
81
  "aria-describedby": active ? statusId : void 0,
114
82
  onClick: () => {
115
83
  toggle(true);
116
- if (!active && !startDisabled) _optionalChain([voiceSession, 'optionalAccess', _9 => _9.onStart, 'call', _10 => _10()]);
84
+ if (!active && !startDisabled) voiceSession.onStart();
117
85
  },
118
86
  children: [
119
87
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.AudioLines, { "aria-hidden": "true", className: "shrink-0" }),
120
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { id: statusId, role: active ? "status" : void 0, className: "truncate", children: active ? status : title })
88
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { id: statusId, role: active ? "status" : void 0, className: "truncate", children: active ? status : unavailable ? "Voice unavailable" : title })
121
89
  ]
122
90
  }
123
91
  ),
@@ -130,10 +98,10 @@ var WorkflowAssistant = _react.forwardRef.call(void 0, function WorkflowAssistan
130
98
  size: "icon",
131
99
  className: "min-h-12 min-w-12 bg-background shadow-lg",
132
100
  onClick: () => {
133
- _optionalChain([launcher, 'access', _11 => _11.current, 'optionalAccess', _12 => _12.focus, 'call', _13 => _13()]);
101
+ _optionalChain([launcher, 'access', _8 => _8.current, 'optionalAccess', _9 => _9.focus, 'call', _10 => _10()]);
134
102
  voiceSession.onEnd();
135
103
  },
136
- "aria-label": _nullishCoalesce(_nullishCoalesce(_optionalChain([labels, 'optionalAccess', _14 => _14.end]), () => ( _optionalChain([voiceSession, 'access', _15 => _15.labels, 'optionalAccess', _16 => _16.end]))), () => ( "End voice chat")),
104
+ "aria-label": _nullishCoalesce(_nullishCoalesce(_optionalChain([labels, 'optionalAccess', _11 => _11.end]), () => ( _optionalChain([voiceSession, 'access', _12 => _12.labels, 'optionalAccess', _13 => _13.end]))), () => ( "End voice chat")),
137
105
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Square, { "aria-hidden": "true" })
138
106
  }
139
107
  )
@@ -163,38 +131,36 @@ var WorkflowAssistant = _react.forwardRef.call(void 0, function WorkflowAssistan
163
131
  type: "button",
164
132
  variant: "ghost",
165
133
  size: "icon",
166
- "aria-label": expanded ? _nullishCoalesce(_optionalChain([labels, 'optionalAccess', _17 => _17.collapse]), () => ( "Reduce panel")) : _nullishCoalesce(_optionalChain([labels, 'optionalAccess', _18 => _18.expand]), () => ( "Expand panel")),
134
+ "aria-label": expanded ? _nullishCoalesce(_optionalChain([labels, 'optionalAccess', _14 => _14.collapse]), () => ( "Reduce panel")) : _nullishCoalesce(_optionalChain([labels, 'optionalAccess', _15 => _15.expand]), () => ( "Expand panel")),
167
135
  onClick: () => onExpandedChange(!expanded),
168
136
  children: expanded ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Minimize2, { "aria-hidden": "true" }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Maximize2, { "aria-hidden": "true" })
169
137
  }
170
138
  ),
171
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkJDEXZGIYcjs.Button, { type: "button", variant: "ghost", size: "icon", "aria-label": _nullishCoalesce(_optionalChain([labels, 'optionalAccess', _19 => _19.minimize]), () => ( "Minimize voice review")), onClick: () => toggle(false), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.ChevronDown, { "aria-hidden": "true" }) })
139
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkJDEXZGIYcjs.Button, { type: "button", variant: "ghost", size: "icon", "aria-label": _nullishCoalesce(_optionalChain([labels, 'optionalAccess', _16 => _16.minimize]), () => ( "Minimize voice review")), onClick: () => toggle(false), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.ChevronDown, { "aria-hidden": "true" }) })
172
140
  ] }),
173
- description && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "shrink-0 px-4 py-2 text-xs text-muted-foreground", children: description }),
174
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
175
- _chunk4YJ6DGPLcjs.ChatThread,
176
- {
177
- messages,
178
- pending,
179
- maxHeight: expanded ? "60dvh" : "32dvh",
180
- className: _chunkKWLSBTB2cjs.cn.call(void 0, "flex-1 px-3", messages.length > 0 || pending ? "min-h-24" : "min-h-0")
181
- }
182
- ),
183
- error && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { role: "alert", className: "shrink-0 px-4 py-2 text-sm text-destructive", children: error }),
184
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "shrink-0 p-2", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
185
- _chunk4YJ6DGPLcjs.ChatInput,
141
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "shrink-0", "data-slot": "workflow-assistant-voice", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
142
+ _chunkYMI3X2YLcjs.VoiceSessionControls,
186
143
  {
187
- value,
188
- onChange,
189
- onSend,
190
- disabled,
191
- pending,
192
- placeholder,
193
- size: "sm",
194
- voice: false,
195
- voiceSession
144
+ ...voiceSession,
145
+ disabled: Boolean(startDisabled),
146
+ size: "hero",
147
+ onEnd: () => {
148
+ _optionalChain([heading, 'access', _17 => _17.current, 'optionalAccess', _18 => _18.focus, 'call', _19 => _19()]);
149
+ voiceSession.onEnd();
150
+ },
151
+ className: _chunkKWLSBTB2cjs.cn.call(void 0, !active && "justify-center px-4 py-6 text-center")
196
152
  }
197
- ) })
153
+ ) }),
154
+ description && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "shrink-0 px-4 py-3 text-sm text-muted-foreground", children: description }),
155
+ error && (voiceSession.state !== "error" || error !== voiceSession.error) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { role: "alert", className: "shrink-0 px-4 py-2 text-sm text-destructive", children: error }),
156
+ pending && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { role: "status", className: "shrink-0 px-4 py-2 text-sm text-muted-foreground", children: "Applying your instructions\u2026" }),
157
+ summaries.length > 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "section", { "aria-label": "Action summaries", className: "min-h-20 flex-1 overflow-y-auto border-t px-4 py-3", children: [
158
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "mb-3 text-xs font-medium text-muted-foreground", children: "Action summaries" }),
159
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ol", { className: "space-y-3", "aria-live": "polite", "aria-relevant": "additions", children: [...summaries].reverse().map((summary) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "li", { className: "space-y-1 border-b pb-3 last:border-0 last:pb-0", children: [
160
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xs text-muted-foreground", children: summary.context }),
161
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "whitespace-pre-wrap break-words text-sm", children: summary.body })
162
+ ] }, summary.id)) })
163
+ ] })
198
164
  ]
199
165
  }
200
166
  );
@@ -1,31 +1,30 @@
1
1
  import * as React from 'react';
2
2
  import { ReactNode } from 'react';
3
- import { ChatMessage } from './chat.cjs';
4
3
  import { VoiceSessionControlsProps } from './voice-session-controls.cjs';
5
4
  import 'react/jsx-runtime';
6
- import './markdown.cjs';
7
- import 'react-markdown';
8
- import './rich-text.cjs';
9
5
 
6
+ interface WorkflowSummary {
7
+ id: string;
8
+ /** Scope at the time of the action, which may differ from the current list. */
9
+ context: string;
10
+ body: string;
11
+ }
10
12
  interface WorkflowAssistantProps {
11
13
  open: boolean;
12
14
  onOpenChange: (open: boolean) => void;
13
15
  expanded?: boolean;
14
16
  onExpandedChange?: (expanded: boolean) => void;
15
17
  title?: string;
16
- /** Current host-owned scope. Keep it visible while the transcript scrolls. */
18
+ /** Current host-owned scope. Keep it visible while the summaries scroll. */
17
19
  context: string;
18
20
  description?: ReactNode;
19
- messages: ChatMessage[];
20
- value: string;
21
- onChange: (value: string) => void;
22
- onSend: (value: string) => void;
21
+ /** Saved action receipts and clarification questions, newest last. Read-only. */
22
+ summaries: WorkflowSummary[];
23
23
  /** Minimizing preserves this host-owned session; only End calls onEnd. */
24
- voiceSession?: VoiceSessionControlsProps;
24
+ voiceSession: VoiceSessionControlsProps;
25
25
  pending?: boolean;
26
26
  disabled?: boolean;
27
27
  error?: string | null;
28
- placeholder?: string;
29
28
  /** Leave room for an existing corner action such as New. */
30
29
  besideCornerAction?: boolean;
31
30
  labels?: {
@@ -37,8 +36,8 @@ interface WorkflowAssistantProps {
37
36
  };
38
37
  className?: string;
39
38
  }
40
- /** A non-modal workflow conversation: the underlying list stays usable.
39
+ /** Voice-only workflow controls: the underlying list stays usable.
41
40
  * The host owns scope, authorization, persistence and the voice connection. */
42
41
  declare const WorkflowAssistant: React.ForwardRefExoticComponent<WorkflowAssistantProps & React.RefAttributes<HTMLElement>>;
43
42
 
44
- export { WorkflowAssistant, type WorkflowAssistantProps };
43
+ export { WorkflowAssistant, type WorkflowAssistantProps, type WorkflowSummary };
@@ -1,31 +1,30 @@
1
1
  import * as React from 'react';
2
2
  import { ReactNode } from 'react';
3
- import { ChatMessage } from './chat.js';
4
3
  import { VoiceSessionControlsProps } from './voice-session-controls.js';
5
4
  import 'react/jsx-runtime';
6
- import './markdown.js';
7
- import 'react-markdown';
8
- import './rich-text.js';
9
5
 
6
+ interface WorkflowSummary {
7
+ id: string;
8
+ /** Scope at the time of the action, which may differ from the current list. */
9
+ context: string;
10
+ body: string;
11
+ }
10
12
  interface WorkflowAssistantProps {
11
13
  open: boolean;
12
14
  onOpenChange: (open: boolean) => void;
13
15
  expanded?: boolean;
14
16
  onExpandedChange?: (expanded: boolean) => void;
15
17
  title?: string;
16
- /** Current host-owned scope. Keep it visible while the transcript scrolls. */
18
+ /** Current host-owned scope. Keep it visible while the summaries scroll. */
17
19
  context: string;
18
20
  description?: ReactNode;
19
- messages: ChatMessage[];
20
- value: string;
21
- onChange: (value: string) => void;
22
- onSend: (value: string) => void;
21
+ /** Saved action receipts and clarification questions, newest last. Read-only. */
22
+ summaries: WorkflowSummary[];
23
23
  /** Minimizing preserves this host-owned session; only End calls onEnd. */
24
- voiceSession?: VoiceSessionControlsProps;
24
+ voiceSession: VoiceSessionControlsProps;
25
25
  pending?: boolean;
26
26
  disabled?: boolean;
27
27
  error?: string | null;
28
- placeholder?: string;
29
28
  /** Leave room for an existing corner action such as New. */
30
29
  besideCornerAction?: boolean;
31
30
  labels?: {
@@ -37,8 +36,8 @@ interface WorkflowAssistantProps {
37
36
  };
38
37
  className?: string;
39
38
  }
40
- /** A non-modal workflow conversation: the underlying list stays usable.
39
+ /** Voice-only workflow controls: the underlying list stays usable.
41
40
  * The host owns scope, authorization, persistence and the voice connection. */
42
41
  declare const WorkflowAssistant: React.ForwardRefExoticComponent<WorkflowAssistantProps & React.RefAttributes<HTMLElement>>;
43
42
 
44
- export { WorkflowAssistant, type WorkflowAssistantProps };
43
+ export { WorkflowAssistant, type WorkflowAssistantProps, type WorkflowSummary };
@@ -1,33 +1,8 @@
1
1
  "use client";
2
2
  "use client";
3
3
  import {
4
- ChatInput,
5
- ChatThread
6
- } from "../chunk-C23Q4FRM.js";
7
- import "../chunk-Z45YKVAM.js";
8
- import "../chunk-ZGTPNSR7.js";
9
- import "../chunk-KF4X37DP.js";
10
- import "../chunk-IJG2B3Y2.js";
11
- import "../chunk-IW4ZIXXG.js";
12
- import "../chunk-OUZSIA5G.js";
13
- import "../chunk-36LNA4WM.js";
14
- import "../chunk-H4XH2PPU.js";
15
- import "../chunk-GA5SX7FE.js";
16
- import "../chunk-QTPPNK6F.js";
17
- import "../chunk-6FC65AZQ.js";
18
- import "../chunk-WHDHUYS6.js";
19
- import "../chunk-VY5U4VGV.js";
20
- import "../chunk-INNGGLMZ.js";
21
- import "../chunk-4HWCNRK4.js";
22
- import "../chunk-V4LE2HWP.js";
23
- import "../chunk-ZRLUUZHK.js";
24
- import "../chunk-F366BHWH.js";
25
- import "../chunk-EIY5LLSP.js";
26
- import "../chunk-NBUWGRQO.js";
27
- import "../chunk-CYDICVH2.js";
28
- import "../chunk-42RTTHND.js";
29
- import "../chunk-QMA3WVB7.js";
30
- import "../chunk-3OWGL4Q2.js";
4
+ VoiceSessionControls
5
+ } from "../chunk-KF4X37DP.js";
31
6
  import "../chunk-5OF6D3GH.js";
32
7
  import {
33
8
  Button
@@ -36,10 +11,6 @@ import {
36
11
  cn
37
12
  } from "../chunk-G6SRSWXB.js";
38
13
  import "../chunk-GJ7S3L6R.js";
39
- import "../chunk-ZWZAAGQF.js";
40
- import "../chunk-RPSRCB5O.js";
41
- import "../chunk-PIU5SSUV.js";
42
- import "../chunk-CS7DM3NV.js";
43
14
 
44
15
  // src/primitives/workflow-assistant.tsx
45
16
  import { forwardRef, useEffect, useId, useRef } from "react";
@@ -62,15 +33,11 @@ var WorkflowAssistant = forwardRef(function WorkflowAssistant2({
62
33
  title = "Voice review",
63
34
  context,
64
35
  description,
65
- messages,
66
- value,
67
- onChange,
68
- onSend,
36
+ summaries,
69
37
  voiceSession,
70
38
  pending,
71
39
  disabled,
72
40
  error,
73
- placeholder = "Describe an action\u2026",
74
41
  besideCornerAction = false,
75
42
  labels,
76
43
  className
@@ -89,9 +56,10 @@ var WorkflowAssistant = forwardRef(function WorkflowAssistant2({
89
56
  moveFocus.current = true;
90
57
  onOpenChange(next);
91
58
  };
92
- const startDisabled = pending || disabled || voiceSession?.disabled;
93
- const active = voiceSession && voiceSession.state !== "disconnected" && voiceSession.state !== "error";
94
- const status = voiceSession && (voiceSession.muted && voiceSession.state === "listening" ? voiceSession.labels?.muted ?? "Microphone muted" : voiceSession.labels?.[voiceSession.state] ?? SESSION_LABELS[voiceSession.state]);
59
+ const startDisabled = pending || disabled || voiceSession.disabled;
60
+ const active = voiceSession.state !== "disconnected" && voiceSession.state !== "error";
61
+ const status = voiceSession.muted && voiceSession.state === "listening" ? voiceSession.labels?.muted ?? "Microphone muted" : voiceSession.labels?.[voiceSession.state] ?? SESSION_LABELS[voiceSession.state];
62
+ const unavailable = voiceSession.state === "error" && voiceSession.disabled;
95
63
  if (!open) return /* @__PURE__ */ jsxs(
96
64
  "aside",
97
65
  {
@@ -107,17 +75,17 @@ var WorkflowAssistant = forwardRef(function WorkflowAssistant2({
107
75
  type: "button",
108
76
  shape: "pill",
109
77
  className: "min-h-12 min-w-12 max-w-full gap-2 shadow-lg",
110
- disabled: startDisabled && !active,
111
- "aria-label": active ? title : labels?.start ?? "Start voice review",
78
+ disabled: startDisabled && !active && !unavailable,
79
+ "aria-label": active ? title : unavailable ? "Voice review unavailable" : labels?.start ?? "Start voice review",
112
80
  "aria-expanded": false,
113
81
  "aria-describedby": active ? statusId : void 0,
114
82
  onClick: () => {
115
83
  toggle(true);
116
- if (!active && !startDisabled) voiceSession?.onStart();
84
+ if (!active && !startDisabled) voiceSession.onStart();
117
85
  },
118
86
  children: [
119
87
  /* @__PURE__ */ jsx(AudioLines, { "aria-hidden": "true", className: "shrink-0" }),
120
- /* @__PURE__ */ jsx("span", { id: statusId, role: active ? "status" : void 0, className: "truncate", children: active ? status : title })
88
+ /* @__PURE__ */ jsx("span", { id: statusId, role: active ? "status" : void 0, className: "truncate", children: active ? status : unavailable ? "Voice unavailable" : title })
121
89
  ]
122
90
  }
123
91
  ),
@@ -170,31 +138,29 @@ var WorkflowAssistant = forwardRef(function WorkflowAssistant2({
170
138
  ),
171
139
  /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon", "aria-label": labels?.minimize ?? "Minimize voice review", onClick: () => toggle(false), children: /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": "true" }) })
172
140
  ] }),
173
- description && /* @__PURE__ */ jsx("div", { className: "shrink-0 px-4 py-2 text-xs text-muted-foreground", children: description }),
174
- /* @__PURE__ */ jsx(
175
- ChatThread,
141
+ /* @__PURE__ */ jsx("div", { className: "shrink-0", "data-slot": "workflow-assistant-voice", children: /* @__PURE__ */ jsx(
142
+ VoiceSessionControls,
176
143
  {
177
- messages,
178
- pending,
179
- maxHeight: expanded ? "60dvh" : "32dvh",
180
- className: cn("flex-1 px-3", messages.length > 0 || pending ? "min-h-24" : "min-h-0")
181
- }
182
- ),
183
- error && /* @__PURE__ */ jsx("p", { role: "alert", className: "shrink-0 px-4 py-2 text-sm text-destructive", children: error }),
184
- /* @__PURE__ */ jsx("div", { className: "shrink-0 p-2", children: /* @__PURE__ */ jsx(
185
- ChatInput,
186
- {
187
- value,
188
- onChange,
189
- onSend,
190
- disabled,
191
- pending,
192
- placeholder,
193
- size: "sm",
194
- voice: false,
195
- voiceSession
144
+ ...voiceSession,
145
+ disabled: Boolean(startDisabled),
146
+ size: "hero",
147
+ onEnd: () => {
148
+ heading.current?.focus();
149
+ voiceSession.onEnd();
150
+ },
151
+ className: cn(!active && "justify-center px-4 py-6 text-center")
196
152
  }
197
- ) })
153
+ ) }),
154
+ description && /* @__PURE__ */ jsx("div", { className: "shrink-0 px-4 py-3 text-sm text-muted-foreground", children: description }),
155
+ error && (voiceSession.state !== "error" || error !== voiceSession.error) && /* @__PURE__ */ jsx("p", { role: "alert", className: "shrink-0 px-4 py-2 text-sm text-destructive", children: error }),
156
+ pending && /* @__PURE__ */ jsx("p", { role: "status", className: "shrink-0 px-4 py-2 text-sm text-muted-foreground", children: "Applying your instructions\u2026" }),
157
+ summaries.length > 0 && /* @__PURE__ */ jsxs("section", { "aria-label": "Action summaries", className: "min-h-20 flex-1 overflow-y-auto border-t px-4 py-3", children: [
158
+ /* @__PURE__ */ jsx("h3", { className: "mb-3 text-xs font-medium text-muted-foreground", children: "Action summaries" }),
159
+ /* @__PURE__ */ jsx("ol", { className: "space-y-3", "aria-live": "polite", "aria-relevant": "additions", children: [...summaries].reverse().map((summary) => /* @__PURE__ */ jsxs("li", { className: "space-y-1 border-b pb-3 last:border-0 last:pb-0", children: [
160
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: summary.context }),
161
+ /* @__PURE__ */ jsx("p", { className: "whitespace-pre-wrap break-words text-sm", children: summary.body })
162
+ ] }, summary.id)) })
163
+ ] })
198
164
  ]
199
165
  }
200
166
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@epicbagel/saas-kit",
3
- "version": "1.21.0",
3
+ "version": "1.22.0",
4
4
  "description": "Accessible React primitives, layout components and design tokens for SaaS apps, built on Radix UI and Tailwind CSS v4.",
5
5
  "license": "MIT",
6
6
  "keywords": [