@epicbagel/saas-kit 1.2.1 → 1.2.3

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 (46) hide show
  1. package/README.md +25 -0
  2. package/dist/{chunk-RSFEKQDR.cjs → chunk-J467F76I.cjs} +3 -1
  3. package/dist/{chunk-HRLP4BHJ.js → chunk-KYQPX754.js} +7 -7
  4. package/dist/{chunk-IH3COANJ.cjs → chunk-N6V3DDKU.cjs} +7 -7
  5. package/dist/{chunk-6RVPQGYS.js → chunk-WNWBKEWV.js} +3 -1
  6. package/dist/primitives/activity-feed.cjs +3 -3
  7. package/dist/primitives/activity-feed.js +4 -4
  8. package/dist/primitives/board-view.cjs +6 -6
  9. package/dist/primitives/board-view.js +5 -5
  10. package/dist/primitives/chat.cjs +57 -30
  11. package/dist/primitives/chat.d.cts +24 -5
  12. package/dist/primitives/chat.d.ts +24 -5
  13. package/dist/primitives/chat.js +50 -23
  14. package/dist/primitives/code-block.cjs +3 -3
  15. package/dist/primitives/code-block.js +2 -2
  16. package/dist/primitives/compact-app-shell.cjs +3 -3
  17. package/dist/primitives/compact-app-shell.js +1 -1
  18. package/dist/primitives/connection.cjs +6 -6
  19. package/dist/primitives/connection.js +7 -7
  20. package/dist/primitives/copy-button.cjs +3 -3
  21. package/dist/primitives/copy-button.js +2 -2
  22. package/dist/primitives/decision-actions.cjs +2 -2
  23. package/dist/primitives/decision-actions.js +1 -1
  24. package/dist/primitives/editable-list.cjs +1 -1
  25. package/dist/primitives/editable-list.js +1 -1
  26. package/dist/primitives/file-dropzone.cjs +3 -3
  27. package/dist/primitives/file-dropzone.js +2 -2
  28. package/dist/primitives/filter-bar.cjs +4 -4
  29. package/dist/primitives/filter-bar.js +3 -3
  30. package/dist/primitives/resource-list.cjs +6 -6
  31. package/dist/primitives/resource-list.js +5 -5
  32. package/dist/primitives/section.cjs +2 -2
  33. package/dist/primitives/section.js +3 -3
  34. package/dist/primitives/stack.cjs +2 -2
  35. package/dist/primitives/stack.d.cts +6 -2
  36. package/dist/primitives/stack.d.ts +6 -2
  37. package/dist/primitives/stack.js +1 -1
  38. package/dist/primitives/switch-field.cjs +2 -2
  39. package/dist/primitives/switch-field.js +3 -3
  40. package/package.json +1 -1
  41. package/dist/{chunk-KADJ56AH.cjs → chunk-6OTAGP2I.cjs} +2 -2
  42. package/dist/{chunk-SGW4FWBX.cjs → chunk-CYH63OCL.cjs} +6 -6
  43. package/dist/{chunk-M7FYGAGO.js → chunk-EHKMVJ6O.js} +3 -3
  44. package/dist/{chunk-VKIGJNJR.cjs → chunk-ENJNZ323.cjs} +2 -2
  45. package/dist/{chunk-MLHNYRFX.js → chunk-PVZ4JGDU.js} +6 -6
  46. package/dist/{chunk-NW3OWKBN.js → chunk-PWOQMTPX.js} +3 -3
package/README.md CHANGED
@@ -135,6 +135,31 @@ public in 1.1.0, and these were the decisions about its props then:
135
135
  - The drop handling follows AI SDK Elements' `PromptInput` and its
136
136
  `globalDrop` (Apache-2.0; see `THIRD_PARTY_NOTICES.md`).
137
137
 
138
+ ### A reply in the background (1.2.3)
139
+
140
+ - **A running turn.** `pending` does two things: it ends the thread on the
141
+ running line, and it locks the composer. A reply worked on in the
142
+ background, while the user keeps writing, needs only the first. Put a turn
143
+ with `status: "running"` in `messages`, and the thread draws the line
144
+ `pending` draws, labelled with the turn's `text` (else `pendingLabel`),
145
+ where the turn sits, while the composer stays free. Replace it with the
146
+ reply when that lands.
147
+
148
+ ```tsx
149
+ <Chat
150
+ messages={[
151
+ ...messages,
152
+ ...(replyOwed ? [{ id: "reply", role: "assistant", status: "running", text: "Reading your files…" } as const] : []),
153
+ ]}
154
+ onSend={send}
155
+ />
156
+ ```
157
+
158
+ - **It is not a message.** The row is the one `pending` draws: its own row
159
+ of the log, which announces it as it appears, with no message id, so the
160
+ scroller neither anchors it nor tracks it. It has no time marker, files or
161
+ rich `content`, and the turns either side of it keep their time grouping.
162
+
138
163
  ## License
139
164
 
140
165
  MIT. Some components and styles are adapted from shadcn/ui, and the file
@@ -12,7 +12,9 @@ var gapStyles = {
12
12
  sm: "gap-2",
13
13
  compact: "gap-3",
14
14
  md: "gap-4",
15
- lg: "gap-6"
15
+ lg: "gap-6",
16
+ xl: "gap-10",
17
+ "2xl": "gap-18"
16
18
  };
17
19
  var directionStyles = {
18
20
  vertical: "flex flex-col",
@@ -7,16 +7,16 @@ import {
7
7
  } from "./chunk-J3GQXM37.js";
8
8
  import {
9
9
  FilterBar
10
- } from "./chunk-MLHNYRFX.js";
11
- import {
12
- Heading
13
- } from "./chunk-H2O6NMLZ.js";
10
+ } from "./chunk-PVZ4JGDU.js";
14
11
  import {
15
12
  Tooltip,
16
13
  TooltipContent,
17
14
  TooltipProvider,
18
15
  TooltipTrigger
19
16
  } from "./chunk-ZRLUUZHK.js";
17
+ import {
18
+ Heading
19
+ } from "./chunk-H2O6NMLZ.js";
20
20
  import {
21
21
  BoardColumnComponent,
22
22
  MobileBoardView
@@ -24,15 +24,15 @@ import {
24
24
  import {
25
25
  ScrollArea
26
26
  } from "./chunk-LELFPLTE.js";
27
+ import {
28
+ useIsMobile
29
+ } from "./chunk-PIU5SSUV.js";
27
30
  import {
28
31
  Input
29
32
  } from "./chunk-QMA3WVB7.js";
30
33
  import {
31
34
  Button
32
35
  } from "./chunk-HQRWRRZJ.js";
33
- import {
34
- useIsMobile
35
- } from "./chunk-PIU5SSUV.js";
36
36
  import {
37
37
  cn
38
38
  } from "./chunk-G6SRSWXB.js";
@@ -7,16 +7,16 @@ var _chunkPNWNU6JWcjs = require('./chunk-PNWNU6JW.cjs');
7
7
  var _chunkFNDBM67Kcjs = require('./chunk-FNDBM67K.cjs');
8
8
 
9
9
 
10
- var _chunkSGW4FWBXcjs = require('./chunk-SGW4FWBX.cjs');
10
+ var _chunkCYH63OCLcjs = require('./chunk-CYH63OCL.cjs');
11
11
 
12
12
 
13
- var _chunkLELBCBDTcjs = require('./chunk-LELBCBDT.cjs');
14
13
 
15
14
 
16
15
 
16
+ var _chunkU2NES7VRcjs = require('./chunk-U2NES7VR.cjs');
17
17
 
18
18
 
19
- var _chunkU2NES7VRcjs = require('./chunk-U2NES7VR.cjs');
19
+ var _chunkLELBCBDTcjs = require('./chunk-LELBCBDT.cjs');
20
20
 
21
21
 
22
22
 
@@ -26,13 +26,13 @@ var _chunkYYFVG5A6cjs = require('./chunk-YYFVG5A6.cjs');
26
26
  var _chunkXLIAY56Vcjs = require('./chunk-XLIAY56V.cjs');
27
27
 
28
28
 
29
- var _chunkPQUSJEXLcjs = require('./chunk-PQUSJEXL.cjs');
29
+ var _chunkR35FT53Gcjs = require('./chunk-R35FT53G.cjs');
30
30
 
31
31
 
32
- var _chunkL4DH72UFcjs = require('./chunk-L4DH72UF.cjs');
32
+ var _chunkPQUSJEXLcjs = require('./chunk-PQUSJEXL.cjs');
33
33
 
34
34
 
35
- var _chunkR35FT53Gcjs = require('./chunk-R35FT53G.cjs');
35
+ var _chunkL4DH72UFcjs = require('./chunk-L4DH72UF.cjs');
36
36
 
37
37
 
38
38
  var _chunkKWLSBTB2cjs = require('./chunk-KWLSBTB2.cjs');
@@ -268,7 +268,7 @@ function ResourceList({
268
268
  const controlsVisible = !(hideControlsWhenEmpty && !loading && !error && _optionalChain([data, 'optionalAccess', _5 => _5.length]) === 0);
269
269
  const filterOnQuickRow = filterBarVisible && !toolbarHasOtherControls && hasQuickFilters;
270
270
  const filterBarNode = filterBarVisible ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
271
- _chunkSGW4FWBXcjs.FilterBar,
271
+ _chunkCYH63OCLcjs.FilterBar,
272
272
  {
273
273
  filters: filterSchema,
274
274
  onFiltersChange,
@@ -12,7 +12,9 @@ var gapStyles = {
12
12
  sm: "gap-2",
13
13
  compact: "gap-3",
14
14
  md: "gap-4",
15
- lg: "gap-6"
15
+ lg: "gap-6",
16
+ xl: "gap-10",
17
+ "2xl": "gap-18"
16
18
  };
17
19
  var directionStyles = {
18
20
  vertical: "flex flex-col",
@@ -4,13 +4,13 @@
4
4
  var _chunkKGFL3VWYcjs = require('../chunk-KGFL3VWY.cjs');
5
5
 
6
6
 
7
+ var _chunkPQUSJEXLcjs = require('../chunk-PQUSJEXL.cjs');
8
+ require('../chunk-VGTINL5Q.cjs');
7
9
 
8
10
 
9
- var _chunkWABCLRBRcjs = require('../chunk-WABCLRBR.cjs');
10
11
 
11
12
 
12
- var _chunkPQUSJEXLcjs = require('../chunk-PQUSJEXL.cjs');
13
- require('../chunk-VGTINL5Q.cjs');
13
+ var _chunkWABCLRBRcjs = require('../chunk-WABCLRBR.cjs');
14
14
  require('../chunk-I6GUOEBO.cjs');
15
15
 
16
16
 
@@ -2,15 +2,15 @@
2
2
  import {
3
3
  ChipTabs
4
4
  } from "../chunk-QD63LB2F.js";
5
+ import {
6
+ Input
7
+ } from "../chunk-QMA3WVB7.js";
8
+ import "../chunk-H7TETFLB.js";
5
9
  import {
6
10
  Avatar,
7
11
  AvatarFallback,
8
12
  AvatarImage
9
13
  } from "../chunk-3OWGL4Q2.js";
10
- import {
11
- Input
12
- } from "../chunk-QMA3WVB7.js";
13
- import "../chunk-H7TETFLB.js";
14
14
  import "../chunk-D4ZL2OEQ.js";
15
15
  import {
16
16
  EmptyState
@@ -2,26 +2,26 @@
2
2
  "use client";
3
3
 
4
4
 
5
- var _chunkIH3COANJcjs = require('../chunk-IH3COANJ.cjs');
5
+ var _chunkN6V3DDKUcjs = require('../chunk-N6V3DDKU.cjs');
6
6
  require('../chunk-PNWNU6JW.cjs');
7
7
  require('../chunk-FNDBM67K.cjs');
8
- require('../chunk-SGW4FWBX.cjs');
8
+ require('../chunk-CYH63OCL.cjs');
9
9
  require('../chunk-PPX2VPGI.cjs');
10
10
  require('../chunk-WNXVGUBF.cjs');
11
11
  require('../chunk-IQZLUT2Y.cjs');
12
- require('../chunk-LELBCBDT.cjs');
13
- require('../chunk-R5L4CM6V.cjs');
14
12
  require('../chunk-U2NES7VR.cjs');
15
13
  require('../chunk-JH4GAGOQ.cjs');
14
+ require('../chunk-LELBCBDT.cjs');
16
15
  require('../chunk-YYFVG5A6.cjs');
17
16
  require('../chunk-XLIAY56V.cjs');
18
17
  require('../chunk-V5SPFLKW.cjs');
18
+ require('../chunk-R5L4CM6V.cjs');
19
+ require('../chunk-R35FT53G.cjs');
19
20
  require('../chunk-PQUSJEXL.cjs');
20
21
  require('../chunk-VGTINL5Q.cjs');
21
22
  require('../chunk-I6GUOEBO.cjs');
22
23
  require('../chunk-VBPPFC7X.cjs');
23
24
  require('../chunk-L4DH72UF.cjs');
24
- require('../chunk-R35FT53G.cjs');
25
25
  require('../chunk-KWLSBTB2.cjs');
26
26
 
27
27
  // src/primitives/board-view.tsx
@@ -57,7 +57,7 @@ function BoardView({
57
57
  onSortChange
58
58
  }) {
59
59
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
60
- _chunkIH3COANJcjs.ResourceList,
60
+ _chunkN6V3DDKUcjs.ResourceList,
61
61
  {
62
62
  data,
63
63
  loading,
@@ -2,26 +2,26 @@
2
2
  "use client";
3
3
  import {
4
4
  ResourceList
5
- } from "../chunk-HRLP4BHJ.js";
5
+ } from "../chunk-KYQPX754.js";
6
6
  import "../chunk-LI5EOSQG.js";
7
7
  import "../chunk-J3GQXM37.js";
8
- import "../chunk-MLHNYRFX.js";
8
+ import "../chunk-PVZ4JGDU.js";
9
9
  import "../chunk-G76JANB4.js";
10
10
  import "../chunk-YG7FBJRM.js";
11
11
  import "../chunk-E2TQMDO7.js";
12
- import "../chunk-H2O6NMLZ.js";
13
- import "../chunk-RRRD5EUI.js";
14
12
  import "../chunk-ZRLUUZHK.js";
15
13
  import "../chunk-OICAYRVH.js";
14
+ import "../chunk-H2O6NMLZ.js";
16
15
  import "../chunk-62UTAG2C.js";
17
16
  import "../chunk-LELFPLTE.js";
18
17
  import "../chunk-J6NXDZR5.js";
18
+ import "../chunk-RRRD5EUI.js";
19
+ import "../chunk-PIU5SSUV.js";
19
20
  import "../chunk-QMA3WVB7.js";
20
21
  import "../chunk-H7TETFLB.js";
21
22
  import "../chunk-D4ZL2OEQ.js";
22
23
  import "../chunk-YEW65ASC.js";
23
24
  import "../chunk-HQRWRRZJ.js";
24
- import "../chunk-PIU5SSUV.js";
25
25
  import "../chunk-G6SRSWXB.js";
26
26
 
27
27
  // src/primitives/board-view.tsx
@@ -10,12 +10,11 @@ var _chunk2BTDBZYNcjs = require('../chunk-2BTDBZYN.cjs');
10
10
  var _chunkEOUO3OROcjs = require('../chunk-EOUO3ORO.cjs');
11
11
 
12
12
 
13
-
14
- var _chunkSUB4BAYEcjs = require('../chunk-SUB4BAYE.cjs');
13
+ var _chunkH2UFRLLNcjs = require('../chunk-H2UFRLLN.cjs');
15
14
 
16
15
 
17
16
 
18
- var _chunkB765DSRGcjs = require('../chunk-B765DSRG.cjs');
17
+ var _chunkSUB4BAYEcjs = require('../chunk-SUB4BAYE.cjs');
19
18
 
20
19
 
21
20
 
@@ -30,24 +29,29 @@ var _chunkXABXUP6Lcjs = require('../chunk-XABXUP6L.cjs');
30
29
  var _chunk2AU7ZRGXcjs = require('../chunk-2AU7ZRGX.cjs');
31
30
 
32
31
 
32
+ var _chunkKENBU3NVcjs = require('../chunk-KENBU3NV.cjs');
33
+ require('../chunk-ELPV44S6.cjs');
33
34
 
34
35
 
35
- var _chunkRIWLAMMEcjs = require('../chunk-RIWLAMME.cjs');
36
- require('../chunk-2HV2KKOE.cjs');
37
36
 
37
+ var _chunkB765DSRGcjs = require('../chunk-B765DSRG.cjs');
38
38
 
39
- var _chunkKENBU3NVcjs = require('../chunk-KENBU3NV.cjs');
40
- require('../chunk-ELPV44S6.cjs');
41
39
 
42
40
 
43
41
 
44
- var _chunkKADJ56AHcjs = require('../chunk-KADJ56AH.cjs');
42
+ var _chunkRIWLAMMEcjs = require('../chunk-RIWLAMME.cjs');
43
+ require('../chunk-2HV2KKOE.cjs');
44
+
45
+
46
+
47
+ var _chunk6OTAGP2Icjs = require('../chunk-6OTAGP2I.cjs');
45
48
 
46
49
 
47
50
 
48
51
 
49
52
 
50
53
  var _chunkZAITUDYDcjs = require('../chunk-ZAITUDYD.cjs');
54
+ require('../chunk-U2NES7VR.cjs');
51
55
 
52
56
 
53
57
 
@@ -65,7 +69,9 @@ require('../chunk-W5HPHEE7.cjs');
65
69
 
66
70
 
67
71
  var _chunk32Q4XOTUcjs = require('../chunk-32Q4XOTU.cjs');
68
- require('../chunk-U2NES7VR.cjs');
72
+
73
+
74
+ var _chunkR35FT53Gcjs = require('../chunk-R35FT53G.cjs');
69
75
 
70
76
 
71
77
  var _chunk2KFZQJH5cjs = require('../chunk-2KFZQJH5.cjs');
@@ -75,12 +81,6 @@ require('../chunk-PQUSJEXL.cjs');
75
81
  var _chunkL4DH72UFcjs = require('../chunk-L4DH72UF.cjs');
76
82
 
77
83
 
78
- var _chunkR35FT53Gcjs = require('../chunk-R35FT53G.cjs');
79
-
80
-
81
- var _chunkH2UFRLLNcjs = require('../chunk-H2UFRLLN.cjs');
82
-
83
-
84
84
  var _chunkKWLSBTB2cjs = require('../chunk-KWLSBTB2.cjs');
85
85
 
86
86
  // src/primitives/chat.tsx
@@ -114,13 +114,32 @@ function useArrivingUserTurnId(messages) {
114
114
  }, [messages]);
115
115
  for (let i = messages.length - 1; i >= 0; i--) {
116
116
  const message = messages[i];
117
- if (message.role === "user") return seen.current.has(message.id) ? void 0 : message.id;
117
+ if (message.role === "user" && message.status !== "running") {
118
+ return seen.current.has(message.id) ? void 0 : message.id;
119
+ }
118
120
  }
119
121
  return void 0;
120
122
  }
123
+ function timelineMarkers(messages, now) {
124
+ let previous = null;
125
+ return messages.map((message) => {
126
+ if (message.status === "running") return null;
127
+ const relativeTime = _chunkH2UFRLLNcjs.formatRelativeLong.call(void 0, message.createdAt, now);
128
+ const opens = relativeTime && relativeTime !== previous ? relativeTime : null;
129
+ previous = relativeTime;
130
+ return opens;
131
+ });
132
+ }
121
133
  function TimelineMarker({ label }) {
122
134
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkB765DSRGcjs.Marker, { variant: "separator", role: "separator", "aria-label": label, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkB765DSRGcjs.MarkerContent, { children: label }) });
123
135
  }
136
+ function ChatRunningLine({
137
+ label,
138
+ align = "start",
139
+ workspace
140
+ }) {
141
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk2AU7ZRGXcjs.Message, { align, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk2AU7ZRGXcjs.MessageContent, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk2BTDBZYNcjs.Trace, { className: workspace ? void 0 : "px-3.5 py-2", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk2BTDBZYNcjs.TraceLine, { status: "running", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk2BTDBZYNcjs.TraceTitle, { children: label }) }) }) }) });
142
+ }
124
143
  var ChatThread = _react.forwardRef.call(void 0,
125
144
  function ChatThread2({
126
145
  messages,
@@ -136,7 +155,7 @@ var ChatThread = _react.forwardRef.call(void 0,
136
155
  attachmentAction = "open",
137
156
  className
138
157
  }, ref) {
139
- const timelineNow = /* @__PURE__ */ new Date();
158
+ const markers = timelineMarkers(messages, /* @__PURE__ */ new Date());
140
159
  const anchorId = useArrivingUserTurnId(messages);
141
160
  const workspace = appearance === "workspace";
142
161
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXABXUP6Lcjs.MessageScrollerProvider, { autoScroll: true, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
@@ -155,10 +174,18 @@ var ChatThread = _react.forwardRef.call(void 0,
155
174
  children: [
156
175
  messages.map((m, index) => {
157
176
  const isUser = m.role === "user";
177
+ if (m.status === "running") {
178
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXABXUP6Lcjs.MessageScrollerItem, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
179
+ ChatRunningLine,
180
+ {
181
+ label: m.text || pendingLabel,
182
+ align: isUser ? "end" : "start",
183
+ workspace
184
+ }
185
+ ) }, m.id);
186
+ }
158
187
  const isFullWidth = m.width === "full";
159
- const relativeTime = _chunkH2UFRLLNcjs.formatRelativeLong.call(void 0, m.createdAt, timelineNow);
160
- const previousRelativeTime = _chunkH2UFRLLNcjs.formatRelativeLong.call(void 0, _optionalChain([messages, 'access', _ => _[index - 1], 'optionalAccess', _2 => _2.createdAt]), timelineNow);
161
- const startsTimelineSection = relativeTime && relativeTime !== previousRelativeTime;
188
+ const marker = markers[index];
162
189
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
163
190
  _chunkXABXUP6Lcjs.MessageScrollerItem,
164
191
  {
@@ -166,7 +193,7 @@ var ChatThread = _react.forwardRef.call(void 0,
166
193
  scrollAnchor: m.id === anchorId,
167
194
  className: _chunkKWLSBTB2cjs.cn.call(void 0, "flex flex-col", workspace ? "gap-5" : "gap-3"),
168
195
  children: [
169
- startsTimelineSection ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TimelineMarker, { label: relativeTime }) : null,
196
+ marker ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TimelineMarker, { label: marker }) : null,
170
197
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk2AU7ZRGXcjs.Message, { align: isUser ? "end" : "start", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk2AU7ZRGXcjs.MessageContent, { children: [
171
198
  (m.content || m.text) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
172
199
  _chunkV4YWTRLDcjs.Bubble,
@@ -202,7 +229,7 @@ var ChatThread = _react.forwardRef.call(void 0,
202
229
  m.id
203
230
  );
204
231
  }),
205
- pending && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXABXUP6Lcjs.MessageScrollerItem, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk2AU7ZRGXcjs.Message, { align: "start", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk2AU7ZRGXcjs.MessageContent, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk2BTDBZYNcjs.Trace, { className: workspace ? void 0 : "px-3.5 py-2", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk2BTDBZYNcjs.TraceLine, { status: "running", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk2BTDBZYNcjs.TraceTitle, { children: pendingLabel }) }) }) }) }) }),
232
+ pending && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkXABXUP6Lcjs.MessageScrollerItem, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ChatRunningLine, { label: pendingLabel, workspace }) }),
206
233
  footer && // Always painted: content-visibility:auto would contain the
207
234
  // footer's paint and layout, clipping a ring or shadow at its
208
235
  // edge and re-parenting anything fixed inside it.
@@ -258,7 +285,7 @@ function ChatAttachmentList({
258
285
  {
259
286
  "aria-label": `${verb} ${attachment.name}`,
260
287
  title: `${verb} ${attachment.name}`,
261
- onClick: () => _optionalChain([onOpen, 'optionalCall', _3 => _3(attachment)]),
288
+ onClick: () => _optionalChain([onOpen, 'optionalCall', _ => _(attachment)]),
262
289
  className: "rounded-xl focus-visible:ring-2 focus-visible:ring-ring/50"
263
290
  }
264
291
  ),
@@ -403,7 +430,7 @@ function ChatInput({
403
430
  "data-slot": "chat-input-actions",
404
431
  onClick: (event) => {
405
432
  if (!event.currentTarget.contains(event.target)) return;
406
- if (!event.target.closest("button")) _optionalChain([ref, 'access', _4 => _4.current, 'optionalAccess', _5 => _5.focus, 'call', _6 => _6()]);
433
+ if (!event.target.closest("button")) _optionalChain([ref, 'access', _2 => _2.current, 'optionalAccess', _3 => _3.focus, 'call', _4 => _4()]);
407
434
  },
408
435
  className: _chunkKWLSBTB2cjs.cn.call(void 0,
409
436
  "gap-2",
@@ -421,7 +448,7 @@ function ChatInput({
421
448
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Plus, { className: _chunkKWLSBTB2cjs.cn.call(void 0, spacious && "h-5 w-5") })
422
449
  }
423
450
  ) }),
424
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkZAITUDYDcjs.DropdownMenuContent, { align: "start", side: "top", className: "min-w-52", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkZAITUDYDcjs.DropdownMenuItem, { onSelect: () => _optionalChain([fileInputRef, 'access', _7 => _7.current, 'optionalAccess', _8 => _8.click, 'call', _9 => _9()]), children: [
451
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkZAITUDYDcjs.DropdownMenuContent, { align: "start", side: "top", className: "min-w-52", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkZAITUDYDcjs.DropdownMenuItem, { onSelect: () => _optionalChain([fileInputRef, 'access', _5 => _5.current, 'optionalAccess', _6 => _6.click, 'call', _7 => _7()]), children: [
425
452
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Paperclip, { className: "h-4 w-4" }),
426
453
  addFilesLabel
427
454
  ] }) })
@@ -652,14 +679,14 @@ var Chat = _react.forwardRef.call(void 0, function Chat2({
652
679
  else if (typeof globalThis.reportError === "function") globalThis.reportError(cause);
653
680
  else console.error(cause);
654
681
  }
655
- window.setTimeout(() => _optionalChain([inputRef, 'access', _10 => _10.current, 'optionalAccess', _11 => _11.focus, 'call', _12 => _12()]), 0);
682
+ window.setTimeout(() => _optionalChain([inputRef, 'access', _8 => _8.current, 'optionalAccess', _9 => _9.focus, 'call', _10 => _10()]), 0);
656
683
  },
657
684
  [attachments, mode, onSend, onSendError, pending]
658
685
  );
659
686
  _react.useImperativeHandle.call(void 0,
660
687
  ref,
661
688
  () => ({
662
- focusInput: () => _optionalChain([inputRef, 'access', _13 => _13.current, 'optionalAccess', _14 => _14.focus, 'call', _15 => _15()]),
689
+ focusInput: () => _optionalChain([inputRef, 'access', _11 => _11.current, 'optionalAccess', _12 => _12.focus, 'call', _13 => _13()]),
663
690
  clearInput: () => setInput("")
664
691
  }),
665
692
  []
@@ -667,7 +694,7 @@ var Chat = _react.forwardRef.call(void 0, function Chat2({
667
694
  const dropFiles = _react.useCallback.call(void 0,
668
695
  (files) => {
669
696
  if (!conversationStarted && mode === "voice") setUserMode("text");
670
- return _optionalChain([onFilesSelected, 'optionalCall', _16 => _16(files)]);
697
+ return _optionalChain([onFilesSelected, 'optionalCall', _14 => _14(files)]);
671
698
  },
672
699
  [conversationStarted, mode, onFilesSelected]
673
700
  );
@@ -676,7 +703,7 @@ var Chat = _react.forwardRef.call(void 0, function Chat2({
676
703
  const showEmptyFileDropzone = emptyFileDropzone && Boolean(onFilesSelected) && attachments.length === 0;
677
704
  const showEmptyPending = !conversationStarted && pending && Boolean(emptyPendingContent);
678
705
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
679
- _chunkKADJ56AHcjs.FileDropArea,
706
+ _chunk6OTAGP2Icjs.FileDropArea,
680
707
  {
681
708
  "data-slot": "chat",
682
709
  "data-layout": layout,
@@ -744,7 +771,7 @@ var Chat = _react.forwardRef.call(void 0, function Chat2({
744
771
  ),
745
772
  children: [
746
773
  showEmptyFileDropzone && onFilesSelected && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
747
- _chunkKADJ56AHcjs.FileDropzone,
774
+ _chunk6OTAGP2Icjs.FileDropzone,
748
775
  {
749
776
  multiple: true,
750
777
  onFiles: onFilesSelected,
@@ -34,12 +34,26 @@ type ChatMessage = {
34
34
  content?: ReactNode;
35
35
  /** Files that belong to this turn. */
36
36
  attachments?: ReadonlyArray<ChatAttachment>;
37
+ /**
38
+ * `"running"`: a reply still being worked on. The thread draws the turn as
39
+ * its running line, the one `pending` adds at the end, labelled with `text`
40
+ * (else the thread's `pendingLabel`), where the turn sits in `messages`.
41
+ * Unlike `pending`, it leaves the composer free, so use it for a reply
42
+ * worked on in the background while the user can keep writing; replace it
43
+ * with the reply when that lands. The line is not a message: it has no time
44
+ * marker, files or rich `content`, and the scroller neither anchors nor
45
+ * tracks it.
46
+ */
47
+ status?: "running";
37
48
  };
38
49
  interface ChatThreadProps {
39
50
  messages: ChatMessage[];
40
- /** Show a running line (`pendingLabel`) at the end of the thread. */
51
+ /**
52
+ * Show a running line (`pendingLabel`) at the end of the thread. A turn with
53
+ * `status: "running"` draws the same line where it sits in `messages`.
54
+ */
41
55
  pending?: boolean;
42
- /** The running line while a reply is pending. Defaults to "Thinking…". */
56
+ /** The running line while a reply is pending, and a running turn's without `text`. Defaults to "Thinking…". */
43
57
  pendingLabel?: string;
44
58
  /** Accessible name of the scroll-to-latest button. Defaults to "Scroll to latest message". */
45
59
  scrollButtonLabel?: string;
@@ -80,7 +94,7 @@ interface ChatThreadProps {
80
94
  * button appears whenever the reader is away from the end. Turns with a
81
95
  * `createdAt` are grouped under relative-time markers ("2 days ago"), and a
82
96
  * pending reply shows as a running trace line, which the log announces as it
83
- * appears.
97
+ * appears. A turn with `status: "running"` draws the same line in its place.
84
98
  */
85
99
  declare const ChatThread: React$1.ForwardRefExoticComponent<ChatThreadProps & React$1.RefAttributes<HTMLDivElement>>;
86
100
  interface ChatInputProps {
@@ -170,9 +184,14 @@ interface ChatProps {
170
184
  * failure itself, with `error`.
171
185
  */
172
186
  onSendError?: (error: unknown) => void;
173
- /** Whether an in-flight request is pending. Disables input and shows a running line (`pendingLabel`). */
187
+ /**
188
+ * Whether an in-flight request is pending. Disables input and shows a
189
+ * running line (`pendingLabel`) at the end of the thread. To show that line
190
+ * and leave the composer free, as for a reply worked on in the background,
191
+ * put a turn with `status: "running"` in `messages` instead.
192
+ */
174
193
  pending?: boolean;
175
- /** The running line while a reply is pending. Defaults to "Thinking…". */
194
+ /** The running line while a reply is pending, and a running turn's without `text`. Defaults to "Thinking…". */
176
195
  pendingLabel?: string;
177
196
  /**
178
197
  * Replaces the empty composer while its first message is in flight. Use for
@@ -34,12 +34,26 @@ type ChatMessage = {
34
34
  content?: ReactNode;
35
35
  /** Files that belong to this turn. */
36
36
  attachments?: ReadonlyArray<ChatAttachment>;
37
+ /**
38
+ * `"running"`: a reply still being worked on. The thread draws the turn as
39
+ * its running line, the one `pending` adds at the end, labelled with `text`
40
+ * (else the thread's `pendingLabel`), where the turn sits in `messages`.
41
+ * Unlike `pending`, it leaves the composer free, so use it for a reply
42
+ * worked on in the background while the user can keep writing; replace it
43
+ * with the reply when that lands. The line is not a message: it has no time
44
+ * marker, files or rich `content`, and the scroller neither anchors nor
45
+ * tracks it.
46
+ */
47
+ status?: "running";
37
48
  };
38
49
  interface ChatThreadProps {
39
50
  messages: ChatMessage[];
40
- /** Show a running line (`pendingLabel`) at the end of the thread. */
51
+ /**
52
+ * Show a running line (`pendingLabel`) at the end of the thread. A turn with
53
+ * `status: "running"` draws the same line where it sits in `messages`.
54
+ */
41
55
  pending?: boolean;
42
- /** The running line while a reply is pending. Defaults to "Thinking…". */
56
+ /** The running line while a reply is pending, and a running turn's without `text`. Defaults to "Thinking…". */
43
57
  pendingLabel?: string;
44
58
  /** Accessible name of the scroll-to-latest button. Defaults to "Scroll to latest message". */
45
59
  scrollButtonLabel?: string;
@@ -80,7 +94,7 @@ interface ChatThreadProps {
80
94
  * button appears whenever the reader is away from the end. Turns with a
81
95
  * `createdAt` are grouped under relative-time markers ("2 days ago"), and a
82
96
  * pending reply shows as a running trace line, which the log announces as it
83
- * appears.
97
+ * appears. A turn with `status: "running"` draws the same line in its place.
84
98
  */
85
99
  declare const ChatThread: React$1.ForwardRefExoticComponent<ChatThreadProps & React$1.RefAttributes<HTMLDivElement>>;
86
100
  interface ChatInputProps {
@@ -170,9 +184,14 @@ interface ChatProps {
170
184
  * failure itself, with `error`.
171
185
  */
172
186
  onSendError?: (error: unknown) => void;
173
- /** Whether an in-flight request is pending. Disables input and shows a running line (`pendingLabel`). */
187
+ /**
188
+ * Whether an in-flight request is pending. Disables input and shows a
189
+ * running line (`pendingLabel`) at the end of the thread. To show that line
190
+ * and leave the composer free, as for a reply worked on in the background,
191
+ * put a turn with `status: "running"` in `messages` instead.
192
+ */
174
193
  pending?: boolean;
175
- /** The running line while a reply is pending. Defaults to "Thinking…". */
194
+ /** The running line while a reply is pending, and a running turn's without `text`. Defaults to "Thinking…". */
176
195
  pendingLabel?: string;
177
196
  /**
178
197
  * Replaces the empty composer while its first message is in flight. Use for