@volter-ai-dev/supercode-ui 0.1.18 → 0.1.20
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/README.md +6 -0
- package/components.mjs +447 -347
- package/composer.mjs +104 -33
- package/controller.mjs +2 -2
- package/conversation.mjs +14 -7
- package/core.mjs +1 -1
- package/embed.mjs +449 -349
- package/icon.mjs +1 -0
- package/index.d.ts +7 -4
- package/messenger.mjs +447 -347
- package/package.json +1 -1
- package/sessions.mjs +3 -2
- package/styles.css +3 -1
package/composer.mjs
CHANGED
|
@@ -82,6 +82,7 @@ function boundedSet(map, key, value) {
|
|
|
82
82
|
// src/icon.jsx
|
|
83
83
|
import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
|
|
84
84
|
var ICONS = {
|
|
85
|
+
attach: () => /* @__PURE__ */ jsx("path", { d: "M6.25 9.75 10.6 5.4a2.1 2.1 0 0 1 2.97 2.97l-5.4 5.4a3.3 3.3 0 0 1-4.67-4.66l5.52-5.52" }),
|
|
85
86
|
back: () => /* @__PURE__ */ jsx("path", { d: "m11.5 4.5-4.5 4.5 4.5 4.5" }),
|
|
86
87
|
check: () => /* @__PURE__ */ jsx("path", { d: "m4 9 3.25 3.25L14 5.5" }),
|
|
87
88
|
chevron: () => /* @__PURE__ */ jsx("path", { d: "m7 4.5 4.5 4.5L7 13.5" }),
|
|
@@ -122,6 +123,44 @@ function UiIcon({ name, size = 16, class: className = "" }) {
|
|
|
122
123
|
return /* @__PURE__ */ jsx("svg", { class: `scui-icon ${className}`, style: { "--scui-icon-size": `${size}px` }, viewBox: "0 0 18 18", fill: "none", stroke: "currentColor", "stroke-width": "1.5", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx(Glyph, {}) });
|
|
123
124
|
}
|
|
124
125
|
|
|
126
|
+
// src/context.jsx
|
|
127
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "preact/jsx-runtime";
|
|
128
|
+
var MAX_CONTEXT_ITEMS = 32;
|
|
129
|
+
function normalizeContext(value) {
|
|
130
|
+
return (Array.isArray(value) ? value : value ? [value] : []).flatMap((item) => {
|
|
131
|
+
if (!item || typeof item.label !== "string" || typeof item.detail !== "string") return [];
|
|
132
|
+
const label = item.label.trim().slice(0, 200);
|
|
133
|
+
const detail = item.detail.slice(0, 2e4);
|
|
134
|
+
if (!label || !detail) return [];
|
|
135
|
+
return [{
|
|
136
|
+
...typeof item.id === "string" && item.id ? { id: item.id.slice(0, 2e3) } : {},
|
|
137
|
+
...typeof item.kind === "string" && item.kind ? { kind: item.kind.slice(0, 100) } : {},
|
|
138
|
+
label,
|
|
139
|
+
detail
|
|
140
|
+
}];
|
|
141
|
+
}).slice(0, MAX_CONTEXT_ITEMS);
|
|
142
|
+
}
|
|
143
|
+
function mergeContext(current, picked) {
|
|
144
|
+
const next = [...current];
|
|
145
|
+
const seen = new Set(current.map((item) => item.id ? `id:${item.id}` : `value:${item.kind ?? ""}\0${item.label}\0${item.detail}`));
|
|
146
|
+
for (const item of normalizeContext(picked)) {
|
|
147
|
+
const key = item.id ? `id:${item.id}` : `value:${item.kind ?? ""}\0${item.label}\0${item.detail}`;
|
|
148
|
+
if (seen.has(key)) continue;
|
|
149
|
+
seen.add(key);
|
|
150
|
+
next.push(item);
|
|
151
|
+
if (next.length === MAX_CONTEXT_ITEMS) break;
|
|
152
|
+
}
|
|
153
|
+
return next;
|
|
154
|
+
}
|
|
155
|
+
function ContextTray({ items, onRemove }) {
|
|
156
|
+
if (!items.length) return null;
|
|
157
|
+
return /* @__PURE__ */ jsx2("div", { class: "scui-compose-context", "aria-label": "Attached context", children: items.map((item, index) => /* @__PURE__ */ jsxs2("span", { children: [
|
|
158
|
+
/* @__PURE__ */ jsx2(UiIcon, { name: "attach", size: 12 }),
|
|
159
|
+
/* @__PURE__ */ jsx2("strong", { children: item.label }),
|
|
160
|
+
/* @__PURE__ */ jsx2("button", { type: "button", "aria-label": `Remove context ${item.label}`, onClick: () => onRemove(index), children: /* @__PURE__ */ jsx2(UiIcon, { name: "close", size: 12 }) })
|
|
161
|
+
] }, item.id ?? `${item.label}:${index}`)) });
|
|
162
|
+
}
|
|
163
|
+
|
|
125
164
|
// src/textarea.js
|
|
126
165
|
import { useLayoutEffect } from "preact/hooks";
|
|
127
166
|
function useAutosizeTextarea(ref, value) {
|
|
@@ -137,7 +176,7 @@ function useAutosizeTextarea(ref, value) {
|
|
|
137
176
|
}
|
|
138
177
|
|
|
139
178
|
// src/composer.jsx
|
|
140
|
-
import { jsx as
|
|
179
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "preact/jsx-runtime";
|
|
141
180
|
var composerMemory = /* @__PURE__ */ new Map();
|
|
142
181
|
function ContinuationBar({ state, adapter, labels = DEFAULT_LABELS }) {
|
|
143
182
|
if (state.mode !== "mirror" || state.canSend) return null;
|
|
@@ -147,29 +186,32 @@ function ContinuationBar({ state, adapter, labels = DEFAULT_LABELS }) {
|
|
|
147
186
|
const resume = canContinueHere(state);
|
|
148
187
|
const join = state.canAttach;
|
|
149
188
|
const branch = state.canBranch;
|
|
150
|
-
if (!resume && !join && !branch) return /* @__PURE__ */
|
|
151
|
-
/* @__PURE__ */
|
|
152
|
-
/* @__PURE__ */
|
|
189
|
+
if (!resume && !join && !branch) return /* @__PURE__ */ jsx3("div", { class: "scui-continuation", children: /* @__PURE__ */ jsxs3("span", { children: [
|
|
190
|
+
/* @__PURE__ */ jsx3("strong", { children: activeElsewhere ? "Active elsewhere" : "Read-only" }),
|
|
191
|
+
/* @__PURE__ */ jsx3("small", { children: "This session cannot be continued by an available harness." })
|
|
153
192
|
] }) });
|
|
154
|
-
return /* @__PURE__ */
|
|
155
|
-
/* @__PURE__ */
|
|
156
|
-
/* @__PURE__ */
|
|
157
|
-
/* @__PURE__ */
|
|
193
|
+
return /* @__PURE__ */ jsxs3("div", { class: "scui-continuation", children: [
|
|
194
|
+
/* @__PURE__ */ jsxs3("span", { children: [
|
|
195
|
+
/* @__PURE__ */ jsx3("strong", { children: activeElsewhere ? "Active elsewhere" : "Read-only" }),
|
|
196
|
+
/* @__PURE__ */ jsx3("small", { children: join ? "Join the proven live runtime without taking it over." : resume ? `Resume this ${harnessDisplayName(state.harness)} session here.` : "Start an independent continuation." })
|
|
158
197
|
] }),
|
|
159
|
-
/* @__PURE__ */
|
|
198
|
+
/* @__PURE__ */ jsx3("button", { type: "button", disabled: Boolean(state.operation), onClick: () => adapter.onIntent(join ? { action: "join" } : resume ? { action: "resume" } : { action: "branch" }), children: join ? labels.joinLive : resume ? labels.continueHere : labels.forkHere })
|
|
160
199
|
] });
|
|
161
200
|
}
|
|
162
201
|
function Composer({ state, adapter, labels = DEFAULT_LABELS, memoryKey = state.attached?.key || `${state.harness}:${state.workspace}`, pendingStatus = null, restoreDraft = null, onPending, onDraftRestored }) {
|
|
163
|
-
const remembered = composerMemory.get(memoryKey) ?? { draft: state.savedDraft, queue: [] };
|
|
202
|
+
const remembered = composerMemory.get(memoryKey) ?? { draft: state.savedDraft, context: [], queue: [] };
|
|
164
203
|
const [draft, setDraft] = useState(remembered.draft);
|
|
204
|
+
const [context, setContext] = useState(remembered.context);
|
|
165
205
|
const [queue, setQueue] = useState(remembered.queue);
|
|
166
206
|
const [dispatching, setDispatching] = useState(false);
|
|
207
|
+
const [picking, setPicking] = useState(false);
|
|
208
|
+
const [pickerError, setPickerError] = useState(null);
|
|
167
209
|
const textarea = useRef(null);
|
|
168
210
|
useAutosizeTextarea(textarea, draft);
|
|
169
|
-
const remember = (nextDraft, nextQueue) => boundedSet(composerMemory, memoryKey, { draft: nextDraft, queue: nextQueue });
|
|
211
|
+
const remember = (nextDraft, nextContext, nextQueue) => boundedSet(composerMemory, memoryKey, { draft: nextDraft, context: nextContext, queue: nextQueue });
|
|
170
212
|
const updateQueue = (update) => setQueue((items) => {
|
|
171
213
|
const next = update(items);
|
|
172
|
-
remember(draft, next);
|
|
214
|
+
remember(draft, context, next);
|
|
173
215
|
return next;
|
|
174
216
|
});
|
|
175
217
|
const queueBlocked = state.busy || pendingStatus !== null || dispatching;
|
|
@@ -179,9 +221,9 @@ function Composer({ state, adapter, labels = DEFAULT_LABELS, memoryKey = state.a
|
|
|
179
221
|
const [next, ...rest] = queue;
|
|
180
222
|
setDispatching(true);
|
|
181
223
|
setQueue(rest);
|
|
182
|
-
remember(draft, rest);
|
|
183
|
-
onPending?.(next);
|
|
184
|
-
adapter.onIntent({ action: "send", text: next });
|
|
224
|
+
remember(draft, context, rest);
|
|
225
|
+
onPending?.(next.text, next.context);
|
|
226
|
+
adapter.onIntent({ action: "send", text: next.text, ...next.context.length ? { context: next.context } : {} });
|
|
185
227
|
}
|
|
186
228
|
}, [adapter, draft, memoryKey, onPending, queue, queueBlocked, state.canSend]);
|
|
187
229
|
useEffect(() => {
|
|
@@ -193,7 +235,9 @@ function Composer({ state, adapter, labels = DEFAULT_LABELS, memoryKey = state.a
|
|
|
193
235
|
useEffect(() => {
|
|
194
236
|
if (!restoreDraft) return;
|
|
195
237
|
setDraft(restoreDraft.text);
|
|
196
|
-
|
|
238
|
+
const restoredContext = normalizeContext(restoreDraft.context);
|
|
239
|
+
setContext(restoredContext);
|
|
240
|
+
remember(restoreDraft.text, restoredContext, queue);
|
|
197
241
|
textarea.current?.focus({ preventScroll: true });
|
|
198
242
|
onDraftRestored?.(restoreDraft.id);
|
|
199
243
|
}, [onDraftRestored, restoreDraft?.id]);
|
|
@@ -201,43 +245,70 @@ function Composer({ state, adapter, labels = DEFAULT_LABELS, memoryKey = state.a
|
|
|
201
245
|
const timer = setTimeout(() => adapter.onIntent({ action: "draft", text: draft }), 250);
|
|
202
246
|
return () => clearTimeout(timer);
|
|
203
247
|
}, [adapter, draft]);
|
|
248
|
+
const pickContext = () => {
|
|
249
|
+
if (!adapter.pickContext || state.mode !== "control" || picking || context.length >= MAX_CONTEXT_ITEMS) return;
|
|
250
|
+
setPicking(true);
|
|
251
|
+
setPickerError(null);
|
|
252
|
+
Promise.resolve().then(() => adapter.pickContext()).then((picked) => {
|
|
253
|
+
setContext((current) => {
|
|
254
|
+
const next = mergeContext(current, picked);
|
|
255
|
+
remember(draft, next, queue);
|
|
256
|
+
return next;
|
|
257
|
+
});
|
|
258
|
+
}, (error) => setPickerError(error instanceof Error ? error.message : "Could not attach context.")).finally(() => setPicking(false));
|
|
259
|
+
};
|
|
204
260
|
const send = () => {
|
|
205
261
|
const text = draft.trim();
|
|
206
262
|
if (!text) return;
|
|
207
|
-
|
|
263
|
+
const message = { text, context };
|
|
264
|
+
if (queuesNewMessage) updateQueue((items) => [...items, message]);
|
|
208
265
|
else if (state.canSend) {
|
|
209
266
|
if (onPending) setDispatching(true);
|
|
210
|
-
onPending?.(text);
|
|
211
|
-
adapter.onIntent({ action: "send", text });
|
|
267
|
+
onPending?.(text, context);
|
|
268
|
+
adapter.onIntent({ action: "send", text, ...context.length ? { context } : {} });
|
|
212
269
|
} else return;
|
|
213
270
|
setDraft("");
|
|
214
|
-
|
|
271
|
+
setContext([]);
|
|
272
|
+
remember("", [], queuesNewMessage ? [...queue, message] : queue);
|
|
215
273
|
};
|
|
216
|
-
return /* @__PURE__ */
|
|
217
|
-
queue.length ? /* @__PURE__ */
|
|
218
|
-
/* @__PURE__ */
|
|
274
|
+
return /* @__PURE__ */ jsxs3("div", { class: "scui-compose", children: [
|
|
275
|
+
queue.length ? /* @__PURE__ */ jsxs3("div", { class: "scui-queue", children: [
|
|
276
|
+
/* @__PURE__ */ jsxs3("strong", { children: [
|
|
219
277
|
queue.length,
|
|
220
278
|
" queued"
|
|
221
279
|
] }),
|
|
222
|
-
queue.map((item, index) => /* @__PURE__ */
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
280
|
+
queue.map((item, index) => /* @__PURE__ */ jsxs3("span", { children: [
|
|
281
|
+
/* @__PURE__ */ jsxs3("span", { children: [
|
|
282
|
+
item.text,
|
|
283
|
+
item.context.length ? /* @__PURE__ */ jsxs3("small", { children: [
|
|
284
|
+
item.context.length,
|
|
285
|
+
" attached"
|
|
286
|
+
] }) : null
|
|
287
|
+
] }),
|
|
288
|
+
/* @__PURE__ */ jsx3("button", { type: "button", "aria-label": `Remove queued message ${index + 1}`, onClick: () => updateQueue((items) => items.filter((_, itemIndex) => itemIndex !== index)), children: /* @__PURE__ */ jsx3(UiIcon, { name: "close", size: 13 }) })
|
|
289
|
+
] }, `${index}:${item.text}`))
|
|
226
290
|
] }) : null,
|
|
227
|
-
/* @__PURE__ */
|
|
228
|
-
|
|
291
|
+
/* @__PURE__ */ jsx3(ContextTray, { items: context, onRemove: (index) => setContext((items) => {
|
|
292
|
+
const next = items.filter((_, itemIndex) => itemIndex !== index);
|
|
293
|
+
remember(draft, next, queue);
|
|
294
|
+
return next;
|
|
295
|
+
}) }),
|
|
296
|
+
pickerError ? /* @__PURE__ */ jsx3("small", { class: "scui-context-error", role: "alert", children: pickerError }) : null,
|
|
297
|
+
/* @__PURE__ */ jsxs3("div", { class: "scui-envelope", children: [
|
|
298
|
+
adapter.pickContext && state.mode === "control" ? /* @__PURE__ */ jsx3("button", { class: "scui-attach", type: "button", "aria-label": "Attach context", disabled: picking || context.length >= MAX_CONTEXT_ITEMS, onClick: pickContext, children: picking ? /* @__PURE__ */ jsx3("i", { class: "scui-control-spinner" }) : /* @__PURE__ */ jsx3(UiIcon, { name: "attach", size: 17 }) }) : null,
|
|
299
|
+
/* @__PURE__ */ jsx3("textarea", { ref: textarea, rows: 1, "aria-label": `Message ${harnessDisplayName(state.harness) || "agent"}`, placeholder: state.startup !== "ready" ? "Connecting\u2026" : pendingStatus === "failed" ? "Retry or edit the unsent message\u2026" : pendingStatus === "editing" ? "Edit and resend\u2026" : queueBlocked ? "Queue a follow-up\u2026" : labels.askAgent, value: draft, disabled: state.mode !== "control" && !state.canSend, onInput: (event) => {
|
|
229
300
|
const value = event.currentTarget.value;
|
|
230
301
|
setDraft(value);
|
|
231
|
-
remember(value, queue);
|
|
302
|
+
remember(value, context, queue);
|
|
232
303
|
}, onKeyDown: (event) => {
|
|
233
304
|
if (isSendKey(event)) {
|
|
234
305
|
event.preventDefault();
|
|
235
306
|
send();
|
|
236
307
|
}
|
|
237
308
|
} }),
|
|
238
|
-
/* @__PURE__ */
|
|
239
|
-
state.busy ? /* @__PURE__ */
|
|
240
|
-
/* @__PURE__ */
|
|
309
|
+
/* @__PURE__ */ jsxs3("span", { children: [
|
|
310
|
+
state.busy ? /* @__PURE__ */ jsx3("button", { class: "scui-stop", type: "button", "aria-label": "Stop agent", disabled: !state.canInterrupt, onClick: () => adapter.onIntent({ action: "interrupt" }), children: /* @__PURE__ */ jsx3(UiIcon, { name: "stop", size: 15 }) }) : null,
|
|
311
|
+
/* @__PURE__ */ jsx3("button", { class: "scui-send", type: "button", "aria-label": queuesNewMessage ? "Queue message" : "Send message", disabled: !draft.trim() || !queuesNewMessage && !state.canSend, onClick: send, children: /* @__PURE__ */ jsx3(UiIcon, { name: queuesNewMessage ? "plus" : "send", size: 17 }) })
|
|
241
312
|
] })
|
|
242
313
|
] })
|
|
243
314
|
] });
|
package/controller.mjs
CHANGED
|
@@ -376,10 +376,10 @@ async function dispatchStandard(controller, intent, options) {
|
|
|
376
376
|
const active = snapshot.activeSessionKey;
|
|
377
377
|
if (intent.action === 'mounted') return;
|
|
378
378
|
if (intent.action === 'attach') return controller.dispatch({ type: 'observe', sessionKey: intent.key });
|
|
379
|
-
if (intent.action === 'send') return controller.dispatch({ type: 'send', text: intent.text });
|
|
379
|
+
if (intent.action === 'send') return controller.dispatch({ type: 'send', text: intent.text, ...(intent.context?.length ? { context: intent.context } : {}) });
|
|
380
380
|
if (intent.action === 'new') {
|
|
381
381
|
await controller.dispatch({ type: 'start', harness: intent.harness });
|
|
382
|
-
return controller.dispatch({ type: 'send', text: intent.text });
|
|
382
|
+
return controller.dispatch({ type: 'send', text: intent.text, ...(intent.context?.length ? { context: intent.context } : {}) });
|
|
383
383
|
}
|
|
384
384
|
if (intent.action === 'resume' && active) return controller.dispatch({ type: 'resume', sessionKey: active });
|
|
385
385
|
if (intent.action === 'join' && active) return controller.dispatch({ type: 'attach', sessionKey: active });
|
package/conversation.mjs
CHANGED
|
@@ -575,6 +575,7 @@ function boundedSet(map, key, value) {
|
|
|
575
575
|
// src/icon.jsx
|
|
576
576
|
import { Fragment, jsx as jsx2, jsxs } from "preact/jsx-runtime";
|
|
577
577
|
var ICONS = {
|
|
578
|
+
attach: () => /* @__PURE__ */ jsx2("path", { d: "M6.25 9.75 10.6 5.4a2.1 2.1 0 0 1 2.97 2.97l-5.4 5.4a3.3 3.3 0 0 1-4.67-4.66l5.52-5.52" }),
|
|
578
579
|
back: () => /* @__PURE__ */ jsx2("path", { d: "m11.5 4.5-4.5 4.5 4.5 4.5" }),
|
|
579
580
|
check: () => /* @__PURE__ */ jsx2("path", { d: "m4 9 3.25 3.25L14 5.5" }),
|
|
580
581
|
chevron: () => /* @__PURE__ */ jsx2("path", { d: "m7 4.5 4.5 4.5L7 13.5" }),
|
|
@@ -1066,18 +1067,23 @@ function Conversation({ state, adapter, components = {}, slots = {}, memoryKey =
|
|
|
1066
1067
|
const element = scroller.current;
|
|
1067
1068
|
if (!element) return;
|
|
1068
1069
|
const anchor = earlierAnchor.current;
|
|
1069
|
-
if (anchor
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1070
|
+
if (anchor) {
|
|
1071
|
+
if (state.operation === "loadEarlier") anchor.seenOperation = true;
|
|
1072
|
+
const prepended = state.transcript.length > anchor.entries && state.transcript[0]?.id !== anchor.firstId;
|
|
1073
|
+
if (prepended) {
|
|
1074
|
+
element.scrollTop = anchor.top + (element.scrollHeight - anchor.height);
|
|
1075
|
+
earlierAnchor.current = null;
|
|
1076
|
+
remember({ top: element.scrollTop, atBottom: false });
|
|
1077
|
+
return;
|
|
1078
|
+
}
|
|
1079
|
+
if (state.error || anchor.seenOperation && state.operation !== "loadEarlier") earlierAnchor.current = null;
|
|
1074
1080
|
}
|
|
1075
1081
|
if (!restored.current) {
|
|
1076
1082
|
restored.current = true;
|
|
1077
1083
|
if (remembered.top !== null && !remembered.atBottom) element.scrollTop = remembered.top;
|
|
1078
1084
|
else pin();
|
|
1079
1085
|
} else if (atBottom) pin();
|
|
1080
|
-
}, [memoryKey, state.transcript, state.busy, state.operation, pendingMessage?.text, pendingMessage?.status]);
|
|
1086
|
+
}, [memoryKey, state.transcript, state.busy, state.operation, state.error, pendingMessage?.text, pendingMessage?.status]);
|
|
1081
1087
|
return /* @__PURE__ */ jsxs2("div", { class: "scui-conversation-wrap", children: [
|
|
1082
1088
|
/* @__PURE__ */ jsx3(ConversationAnnouncements, { state }),
|
|
1083
1089
|
/* @__PURE__ */ jsx3("div", { class: "scui-conversation", ref: scroller, tabIndex: 0, "aria-label": "Conversation", onScroll: (event) => {
|
|
@@ -1091,7 +1097,7 @@ function Conversation({ state, adapter, components = {}, slots = {}, memoryKey =
|
|
|
1091
1097
|
/* @__PURE__ */ jsx3(SessionDetails, { semantics: state.semantics }),
|
|
1092
1098
|
state.history.hasEarlier ? /* @__PURE__ */ jsx3("button", { class: "scui-load", type: "button", disabled: Boolean(state.operation), onClick: () => {
|
|
1093
1099
|
const element = scroller.current;
|
|
1094
|
-
if (element) earlierAnchor.current = { height: element.scrollHeight, top: element.scrollTop, entries: state.transcript.length };
|
|
1100
|
+
if (element) earlierAnchor.current = { height: element.scrollHeight, top: element.scrollTop, entries: state.transcript.length, firstId: state.transcript[0]?.id, seenOperation: false };
|
|
1095
1101
|
setAtBottom(false);
|
|
1096
1102
|
adapter.onIntent({ action: "loadEarlier" });
|
|
1097
1103
|
}, children: "Load earlier messages" }) : null,
|
|
@@ -1103,6 +1109,7 @@ function Conversation({ state, adapter, components = {}, slots = {}, memoryKey =
|
|
|
1103
1109
|
] }, block.id)),
|
|
1104
1110
|
pendingMessage ? /* @__PURE__ */ jsxs2("article", { class: "scui-message scui-pending", "data-role": "user", "data-status": pendingMessage.status, "aria-label": "Your pending message", children: [
|
|
1105
1111
|
/* @__PURE__ */ jsx3(Markdown, { value: pendingMessage.text, copyText: adapter?.copyText }),
|
|
1112
|
+
/* @__PURE__ */ jsx3(ContextDisclosure, { context: pendingMessage.context }),
|
|
1106
1113
|
/* @__PURE__ */ jsxs2("footer", { children: [
|
|
1107
1114
|
/* @__PURE__ */ jsx3("small", { children: pendingMessage.status === "failed" ? "Not sent" : "Sending\u2026" }),
|
|
1108
1115
|
pendingMessage.status === "failed" ? /* @__PURE__ */ jsxs2("span", { children: [
|
package/core.mjs
CHANGED
|
@@ -721,7 +721,7 @@ export function sessionActivity(state, row) {
|
|
|
721
721
|
export function filterSessions(rows, query) {
|
|
722
722
|
const needle = query.trim().toLocaleLowerCase();
|
|
723
723
|
if (!needle) return [...rows];
|
|
724
|
-
return rows.filter((row) => [row.name, row.title, row.cwd, row.harness, harnessDisplayName(row.harness)].some((value) => value.toLocaleLowerCase().includes(needle)));
|
|
724
|
+
return rows.filter((row) => [row.name, row.title, row.preview, row.cwd, row.harness, harnessDisplayName(row.harness)].some((value) => typeof value === 'string' && value.toLocaleLowerCase().includes(needle)));
|
|
725
725
|
}
|
|
726
726
|
|
|
727
727
|
export function groupConversation(entries) {
|