@volter-ai-dev/supercode-ui 0.1.69 → 0.1.71
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 +37 -1
- package/activity.mjs +5 -1235
- package/chunks/chunk-ATCOWFRV.mjs +105 -0
- package/chunks/chunk-LOP6XOON.mjs +671 -0
- package/chunks/chunk-LQMYNJPU.mjs +120 -0
- package/chunks/chunk-LS6JBXNT.mjs +1237 -0
- package/chunks/chunk-O7Q2PELK.mjs +201 -0
- package/chunks/chunk-OW42DS6P.mjs +842 -0
- package/chunks/chunk-SJ3YTA6Z.mjs +316 -0
- package/chunks/chunk-SSYNT434.mjs +224 -0
- package/chunks/chunk-V3UM7H7W.mjs +328 -0
- package/chunks/chunk-XD2WJYSL.mjs +29 -0
- package/chunks/chunk-ZLYHUYE2.mjs +62 -0
- package/components.d.ts +3 -0
- package/components.mjs +59 -3766
- package/composer.mjs +8 -580
- package/conversation.mjs +16 -1373
- package/embed.mjs +15 -3681
- package/icon.mjs +3 -58
- package/index.d.ts +25 -0
- package/logo.mjs +5 -87
- package/messenger.d.ts +3 -0
- package/messenger.mjs +21 -3677
- package/package.json +3 -2
- package/react/activity.mjs +5 -1235
- package/react/chunks/chunk-2RIHDJT6.mjs +842 -0
- package/react/chunks/chunk-7ES5FSLG.mjs +316 -0
- package/react/chunks/chunk-GV5KV5UY.mjs +105 -0
- package/react/chunks/chunk-GYQOTTZ5.mjs +224 -0
- package/react/chunks/chunk-LS6JBXNT.mjs +1237 -0
- package/react/chunks/chunk-OINC7LV7.mjs +62 -0
- package/react/chunks/chunk-TQHX2DQG.mjs +120 -0
- package/react/chunks/chunk-UKHDCPME.mjs +328 -0
- package/react/chunks/chunk-UKMTRNJN.mjs +671 -0
- package/react/chunks/chunk-ZM5X5LOF.mjs +29 -0
- package/react/chunks/chunk-ZXD7NZXI.mjs +201 -0
- package/react/components.mjs +59 -3766
- package/react/composer.mjs +8 -580
- package/react/conversation.mjs +16 -1373
- package/react/icon.mjs +3 -58
- package/react/index.d.ts +25 -0
- package/react/logo.mjs +5 -87
- package/react/messenger.d.ts +3 -0
- package/react/messenger.mjs +21 -3677
- package/react/sessions.mjs +9 -519
- package/react/settings.mjs +9 -425
- package/react/subagents.mjs +8 -1546
- package/sessions.mjs +9 -519
- package/settings.mjs +9 -425
- package/styles.css +12 -0
- package/subagents.mjs +8 -1546
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
import {
|
|
2
|
+
UiIcon
|
|
3
|
+
} from "./chunk-ZLYHUYE2.mjs";
|
|
4
|
+
|
|
5
|
+
// src/memory.js
|
|
6
|
+
var MEMORY_LIMIT = 100;
|
|
7
|
+
var registry = /* @__PURE__ */ new Set();
|
|
8
|
+
function uiMemory() {
|
|
9
|
+
const map = /* @__PURE__ */ new Map();
|
|
10
|
+
registry.add(map);
|
|
11
|
+
return map;
|
|
12
|
+
}
|
|
13
|
+
function resetSupercodeUiMemory() {
|
|
14
|
+
for (const map of registry) map.clear();
|
|
15
|
+
}
|
|
16
|
+
function boundedSet(map, key, value) {
|
|
17
|
+
map.delete(key);
|
|
18
|
+
map.set(key, value);
|
|
19
|
+
while (map.size > MEMORY_LIMIT) map.delete(map.keys().next().value);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// src/context.jsx
|
|
23
|
+
import { useEffect, useRef, useState } from "preact/hooks";
|
|
24
|
+
import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
|
|
25
|
+
var MAX_CONTEXT_ITEMS = 32;
|
|
26
|
+
var MAX_IMAGE_ITEMS = 4;
|
|
27
|
+
var MAX_IMAGE_BYTES = 5 * 1024 * 1024;
|
|
28
|
+
var MAX_RESOLVED_IMAGE_BYTES = 16 * 1024 * 1024;
|
|
29
|
+
var IMAGE_TYPES = /* @__PURE__ */ new Set(["image/png", "image/jpeg", "image/gif", "image/webp"]);
|
|
30
|
+
function normalizeContext(value) {
|
|
31
|
+
return (Array.isArray(value) ? value : value ? [value] : []).flatMap((item) => {
|
|
32
|
+
if (!item || typeof item.label !== "string" || typeof item.detail !== "string") return [];
|
|
33
|
+
const label = item.label.trim().slice(0, 200);
|
|
34
|
+
const detail = item.detail.slice(0, 2e4);
|
|
35
|
+
if (!label || !detail) return [];
|
|
36
|
+
return [{
|
|
37
|
+
...typeof item.id === "string" && item.id ? { id: item.id.slice(0, 2e3) } : {},
|
|
38
|
+
...typeof item.kind === "string" && item.kind ? { kind: item.kind.slice(0, 100) } : {},
|
|
39
|
+
label,
|
|
40
|
+
detail
|
|
41
|
+
}];
|
|
42
|
+
}).slice(0, MAX_CONTEXT_ITEMS);
|
|
43
|
+
}
|
|
44
|
+
function mergeContext(current, picked) {
|
|
45
|
+
const next = [...current];
|
|
46
|
+
const seen = new Set(current.map((item) => item.id ? `id:${item.id}` : `value:${item.kind ?? ""}\0${item.label}\0${item.detail}`));
|
|
47
|
+
for (const item of normalizeContext(picked)) {
|
|
48
|
+
const key = item.id ? `id:${item.id}` : `value:${item.kind ?? ""}\0${item.label}\0${item.detail}`;
|
|
49
|
+
if (seen.has(key)) continue;
|
|
50
|
+
seen.add(key);
|
|
51
|
+
next.push(item);
|
|
52
|
+
if (next.length === MAX_CONTEXT_ITEMS) break;
|
|
53
|
+
}
|
|
54
|
+
return next;
|
|
55
|
+
}
|
|
56
|
+
function normalizeImages(value) {
|
|
57
|
+
const seen = /* @__PURE__ */ new Set();
|
|
58
|
+
return (Array.isArray(value) ? value : value ? [value] : []).flatMap((item) => {
|
|
59
|
+
if (!item || typeof item.label !== "string" || typeof item.url !== "string") return [];
|
|
60
|
+
const label = item.label.trim().slice(0, 200);
|
|
61
|
+
const url = item.url;
|
|
62
|
+
if (!label || seen.has(url) || !(url.startsWith("data:image/") || url.startsWith("https://") || url.startsWith("http://"))) return [];
|
|
63
|
+
seen.add(url);
|
|
64
|
+
return [{
|
|
65
|
+
...typeof item.id === "string" && item.id ? { id: item.id.slice(0, 2e3) } : {},
|
|
66
|
+
label,
|
|
67
|
+
url
|
|
68
|
+
}];
|
|
69
|
+
}).slice(0, MAX_IMAGE_ITEMS);
|
|
70
|
+
}
|
|
71
|
+
function mergeImages(current, picked) {
|
|
72
|
+
const next = [...current];
|
|
73
|
+
const seen = new Set(current.map((item) => item.url));
|
|
74
|
+
for (const item of normalizeImages(picked)) {
|
|
75
|
+
if (seen.has(item.url)) continue;
|
|
76
|
+
seen.add(item.url);
|
|
77
|
+
next.push(item);
|
|
78
|
+
if (next.length === MAX_IMAGE_ITEMS) break;
|
|
79
|
+
}
|
|
80
|
+
return next;
|
|
81
|
+
}
|
|
82
|
+
function partitionAttachments(value) {
|
|
83
|
+
const values = Array.isArray(value) ? value : value ? [value] : [];
|
|
84
|
+
const context = [];
|
|
85
|
+
const images = [];
|
|
86
|
+
for (const item of values) {
|
|
87
|
+
if (item && typeof item.label === "string" && item.label.trim() && typeof item.detail === "string" && item.detail) context.push(item);
|
|
88
|
+
else if (item && typeof item.label === "string" && item.label.trim() && typeof item.url === "string" && (item.url.startsWith("data:image/") || item.url.startsWith("https://") || item.url.startsWith("http://"))) images.push(item);
|
|
89
|
+
else throw new Error("The attachment picker returned an invalid item.");
|
|
90
|
+
}
|
|
91
|
+
return { context, images };
|
|
92
|
+
}
|
|
93
|
+
function normalizeAttachmentCandidates(value) {
|
|
94
|
+
const candidates = [];
|
|
95
|
+
for (const item of Array.isArray(value) ? value : []) {
|
|
96
|
+
const context = normalizeContext(item)[0];
|
|
97
|
+
if (context) {
|
|
98
|
+
candidates.push(context);
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
const image = normalizeImages(item)[0];
|
|
102
|
+
if (image) candidates.push(image);
|
|
103
|
+
}
|
|
104
|
+
return candidates.slice(0, MAX_CONTEXT_ITEMS + MAX_IMAGE_ITEMS);
|
|
105
|
+
}
|
|
106
|
+
function attachmentKey(item) {
|
|
107
|
+
if (item.id) return `id:${item.id}`;
|
|
108
|
+
return "detail" in item ? `context:${item.kind ?? ""}\0${item.label}\0${item.detail}` : `image:${item.url}`;
|
|
109
|
+
}
|
|
110
|
+
function ContextCandidate({ attachment, attached, onAttach }) {
|
|
111
|
+
const image = "url" in attachment;
|
|
112
|
+
return /* @__PURE__ */ jsxs("button", { type: "button", disabled: attached, "aria-label": `${attached ? "Attached" : "Attach"} ${attachment.label}`, onClick: () => onAttach(attachment), children: [
|
|
113
|
+
image ? /* @__PURE__ */ jsx("img", { src: attachment.url, alt: "" }) : /* @__PURE__ */ jsx(UiIcon, { name: "attach", size: 13 }),
|
|
114
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
115
|
+
/* @__PURE__ */ jsx("strong", { children: attachment.label }),
|
|
116
|
+
/* @__PURE__ */ jsx("small", { children: image ? "Image" : attachment.kind || "Context" })
|
|
117
|
+
] }),
|
|
118
|
+
attached ? /* @__PURE__ */ jsx(UiIcon, { name: "check", size: 13 }) : /* @__PURE__ */ jsx(UiIcon, { name: "plus", size: 13 })
|
|
119
|
+
] });
|
|
120
|
+
}
|
|
121
|
+
function ContextCandidates({ items, context, images, state, adapter, onAttach, component: Candidate = ContextCandidate }) {
|
|
122
|
+
if (!items.length) return null;
|
|
123
|
+
const attached = new Set([...context, ...images].map(attachmentKey));
|
|
124
|
+
return /* @__PURE__ */ jsx("div", { className: "scui-context-candidates", "aria-label": "Available context", children: items.map((attachment, index) => /* @__PURE__ */ jsx(Candidate, { value: attachment, attachment, attached: attached.has(attachmentKey(attachment)), state, adapter, onAttach, index }, attachmentKey(attachment))) });
|
|
125
|
+
}
|
|
126
|
+
async function imageAttachmentsFromFiles(value) {
|
|
127
|
+
const files = Array.from(value ?? []).filter((file) => file?.type?.startsWith("image/"));
|
|
128
|
+
if (files.length > MAX_IMAGE_ITEMS) throw new Error(`Attach at most ${MAX_IMAGE_ITEMS} images at a time.`);
|
|
129
|
+
return Promise.all(files.map(async (file) => {
|
|
130
|
+
if (!IMAGE_TYPES.has(file.type)) throw new Error(`${file.name || "That image"} is not PNG, JPEG, GIF, or WebP.`);
|
|
131
|
+
if (file.size > MAX_IMAGE_BYTES) throw new Error(`${file.name || "That image"} is larger than 5 MB.`);
|
|
132
|
+
const url = await new Promise((resolve, reject) => {
|
|
133
|
+
const reader = new FileReader();
|
|
134
|
+
reader.onload = () => resolve(reader.result);
|
|
135
|
+
reader.onerror = () => reject(reader.error ?? new Error(`Could not read ${file.name || "image"}.`));
|
|
136
|
+
reader.readAsDataURL(file);
|
|
137
|
+
});
|
|
138
|
+
return { id: `${file.name}:${file.size}:${file.lastModified}`, label: file.name || "Pasted image", url };
|
|
139
|
+
}));
|
|
140
|
+
}
|
|
141
|
+
function ContextTray({ items, onRemove }) {
|
|
142
|
+
if (!items.length) return null;
|
|
143
|
+
return /* @__PURE__ */ jsx("div", { className: "scui-compose-context", "aria-label": "Attached context", children: items.map((item, index) => /* @__PURE__ */ jsxs("span", { children: [
|
|
144
|
+
/* @__PURE__ */ jsx(UiIcon, { name: "attach", size: 12 }),
|
|
145
|
+
/* @__PURE__ */ jsx("strong", { children: item.label }),
|
|
146
|
+
/* @__PURE__ */ jsx("button", { type: "button", "aria-label": `Remove context ${item.label}`, onClick: () => onRemove(index), children: /* @__PURE__ */ jsx(UiIcon, { name: "close", size: 12 }) })
|
|
147
|
+
] }, item.id ?? `${item.label}:${index}`)) });
|
|
148
|
+
}
|
|
149
|
+
function ImageTray({ items, onRemove }) {
|
|
150
|
+
if (!items.length) return null;
|
|
151
|
+
return /* @__PURE__ */ jsx("div", { className: "scui-compose-images", "aria-label": "Attached images", children: items.map((item, index) => /* @__PURE__ */ jsxs("span", { children: [
|
|
152
|
+
/* @__PURE__ */ jsx("img", { src: item.url, alt: "" }),
|
|
153
|
+
/* @__PURE__ */ jsx("strong", { children: item.label }),
|
|
154
|
+
onRemove ? /* @__PURE__ */ jsx("button", { type: "button", "aria-label": `Remove image ${item.label}`, onClick: () => onRemove(index), children: /* @__PURE__ */ jsx(UiIcon, { name: "close", size: 12 }) }) : null
|
|
155
|
+
] }, item.id ?? `${item.label}:${index}`)) });
|
|
156
|
+
}
|
|
157
|
+
function imageFilename(label) {
|
|
158
|
+
const value = label.trim().replace(/[\\/:*?"<>|]+/g, "-");
|
|
159
|
+
return value || "image";
|
|
160
|
+
}
|
|
161
|
+
function ImageViewer({ items, index, adapter, onChange, onClose }) {
|
|
162
|
+
const dialog = useRef(null);
|
|
163
|
+
const reset = useRef(null);
|
|
164
|
+
const resolutions = useRef(/* @__PURE__ */ new Map());
|
|
165
|
+
const alive = useRef(true);
|
|
166
|
+
const [, redraw] = useState(0);
|
|
167
|
+
const [copyState, setCopyState] = useState("idle");
|
|
168
|
+
const item = items[index];
|
|
169
|
+
const key = item?.reference ?? item?.url ?? `${item?.id ?? ""}:${index}`;
|
|
170
|
+
const resolution = item?.url ? null : resolutions.current.get(key);
|
|
171
|
+
const imageUrl = item?.url ?? (resolution?.status === "ready" ? resolution.url : null);
|
|
172
|
+
const remote = imageUrl?.startsWith("http://") || imageUrl?.startsWith("https://");
|
|
173
|
+
const resolve = (candidate, force = false) => {
|
|
174
|
+
if (candidate?.url || !candidate?.reference || !adapter?.resolveImage) return;
|
|
175
|
+
const candidateKey = candidate.reference;
|
|
176
|
+
const current = resolutions.current.get(candidateKey);
|
|
177
|
+
if (!force && (current?.status === "loading" || current?.status === "ready")) return;
|
|
178
|
+
if (current?.url) URL.revokeObjectURL(current.url);
|
|
179
|
+
resolutions.current.set(candidateKey, { status: "loading" });
|
|
180
|
+
redraw((value) => value + 1);
|
|
181
|
+
Promise.resolve().then(() => adapter.resolveImage(candidate)).then((blob) => {
|
|
182
|
+
if (!(blob instanceof Blob) || !blob.type.startsWith("image/")) throw new Error("The host returned an invalid image.");
|
|
183
|
+
if (blob.size > MAX_RESOLVED_IMAGE_BYTES) throw new Error("This image is too large to preview safely.");
|
|
184
|
+
if (!alive.current) return;
|
|
185
|
+
const url = URL.createObjectURL(blob);
|
|
186
|
+
resolutions.current.set(candidateKey, { status: "ready", url });
|
|
187
|
+
redraw((value) => value + 1);
|
|
188
|
+
}).catch((error) => {
|
|
189
|
+
if (!alive.current) return;
|
|
190
|
+
resolutions.current.set(candidateKey, {
|
|
191
|
+
status: "error",
|
|
192
|
+
message: error instanceof Error && error.message ? error.message : "Could not load this image."
|
|
193
|
+
});
|
|
194
|
+
redraw((value) => value + 1);
|
|
195
|
+
});
|
|
196
|
+
};
|
|
197
|
+
useEffect(() => {
|
|
198
|
+
alive.current = true;
|
|
199
|
+
if (!dialog.current?.open) dialog.current?.showModal();
|
|
200
|
+
return () => {
|
|
201
|
+
alive.current = false;
|
|
202
|
+
clearTimeout(reset.current);
|
|
203
|
+
for (const value of resolutions.current.values()) if (value.url) URL.revokeObjectURL(value.url);
|
|
204
|
+
resolutions.current.clear();
|
|
205
|
+
};
|
|
206
|
+
}, []);
|
|
207
|
+
useEffect(() => {
|
|
208
|
+
clearTimeout(reset.current);
|
|
209
|
+
setCopyState("idle");
|
|
210
|
+
resolve(item);
|
|
211
|
+
}, [index, item?.reference]);
|
|
212
|
+
if (!item || !item.url && (!item.reference || !adapter?.resolveImage)) return null;
|
|
213
|
+
const move = (amount) => onChange((index + amount + items.length) % items.length);
|
|
214
|
+
const copy = async () => {
|
|
215
|
+
try {
|
|
216
|
+
await adapter.copyText(imageUrl);
|
|
217
|
+
setCopyState("copied");
|
|
218
|
+
} catch {
|
|
219
|
+
setCopyState("failed");
|
|
220
|
+
}
|
|
221
|
+
clearTimeout(reset.current);
|
|
222
|
+
reset.current = setTimeout(() => setCopyState("idle"), 1500);
|
|
223
|
+
};
|
|
224
|
+
const close = () => dialog.current?.close();
|
|
225
|
+
return /* @__PURE__ */ jsxs(
|
|
226
|
+
"dialog",
|
|
227
|
+
{
|
|
228
|
+
ref: dialog,
|
|
229
|
+
className: "scui-image-viewer",
|
|
230
|
+
"aria-label": `Image preview: ${item.label}`,
|
|
231
|
+
onClose,
|
|
232
|
+
onClick: (event) => {
|
|
233
|
+
if (event.target === event.currentTarget) close();
|
|
234
|
+
},
|
|
235
|
+
onKeyDown: (event) => {
|
|
236
|
+
if (items.length < 2 || !["ArrowLeft", "ArrowRight"].includes(event.key)) return;
|
|
237
|
+
event.preventDefault();
|
|
238
|
+
move(event.key === "ArrowLeft" ? -1 : 1);
|
|
239
|
+
},
|
|
240
|
+
children: [
|
|
241
|
+
/* @__PURE__ */ jsxs("header", { children: [
|
|
242
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
243
|
+
/* @__PURE__ */ jsx("strong", { children: item.label }),
|
|
244
|
+
items.length > 1 ? /* @__PURE__ */ jsxs("small", { children: [
|
|
245
|
+
index + 1,
|
|
246
|
+
" of ",
|
|
247
|
+
items.length
|
|
248
|
+
] }) : null
|
|
249
|
+
] }),
|
|
250
|
+
/* @__PURE__ */ jsxs("nav", { "aria-label": "Image actions", children: [
|
|
251
|
+
remote && adapter?.copyText ? /* @__PURE__ */ jsx("button", { type: "button", "aria-label": copyState === "copied" ? "Image link copied" : copyState === "failed" ? "Could not copy image link" : "Copy image link", title: "Copy image link", "data-status": copyState, onClick: copy, children: /* @__PURE__ */ jsx(UiIcon, { name: copyState === "copied" ? "check" : "copy", size: 16 }) }) : null,
|
|
252
|
+
imageUrl ? remote ? /* @__PURE__ */ jsx("a", { href: imageUrl, target: "_blank", rel: "noreferrer", "aria-label": "Open original image", title: "Open original image", children: /* @__PURE__ */ jsx(UiIcon, { name: "image", size: 16 }) }) : /* @__PURE__ */ jsx("a", { href: imageUrl, download: imageFilename(item.label), "aria-label": "Download image", title: "Download image", children: /* @__PURE__ */ jsx(UiIcon, { name: "down", size: 16 }) }) : null,
|
|
253
|
+
/* @__PURE__ */ jsx("button", { type: "button", "aria-label": "Close image preview", title: "Close", onClick: close, children: /* @__PURE__ */ jsx(UiIcon, { name: "close", size: 17 }) })
|
|
254
|
+
] })
|
|
255
|
+
] }),
|
|
256
|
+
/* @__PURE__ */ jsxs("figure", { children: [
|
|
257
|
+
imageUrl ? /* @__PURE__ */ jsx("img", { src: imageUrl, alt: item.label }) : resolution?.status === "error" ? /* @__PURE__ */ jsxs("div", { className: "scui-image-resolution", role: "alert", children: [
|
|
258
|
+
/* @__PURE__ */ jsx(UiIcon, { name: "image", size: 28 }),
|
|
259
|
+
/* @__PURE__ */ jsx("strong", { children: "Could not load image" }),
|
|
260
|
+
/* @__PURE__ */ jsx("small", { children: resolution.message }),
|
|
261
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: () => resolve(item, true), children: "Retry" })
|
|
262
|
+
] }) : /* @__PURE__ */ jsxs("div", { className: "scui-image-resolution", role: "status", children: [
|
|
263
|
+
/* @__PURE__ */ jsx("i", { className: "scui-control-spinner" }),
|
|
264
|
+
/* @__PURE__ */ jsx("strong", { children: "Loading image\u2026" }),
|
|
265
|
+
/* @__PURE__ */ jsx("small", { children: "The original stays out of the transcript payload." })
|
|
266
|
+
] }),
|
|
267
|
+
items.length > 1 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
268
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "scui-image-previous", "aria-label": "Previous image", onClick: () => move(-1), children: /* @__PURE__ */ jsx(UiIcon, { name: "chevron", size: 19 }) }),
|
|
269
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "scui-image-next", "aria-label": "Next image", onClick: () => move(1), children: /* @__PURE__ */ jsx(UiIcon, { name: "chevron", size: 19 }) })
|
|
270
|
+
] }) : null
|
|
271
|
+
] })
|
|
272
|
+
]
|
|
273
|
+
}
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
function MessageImages({ items, adapter }) {
|
|
277
|
+
const [active, setActive] = useState(null);
|
|
278
|
+
const opener = useRef(null);
|
|
279
|
+
if (!items?.length) return null;
|
|
280
|
+
const viewable = items.filter((item) => item.url || item.reference && adapter?.resolveImage);
|
|
281
|
+
const close = () => {
|
|
282
|
+
setActive(null);
|
|
283
|
+
requestAnimationFrame(() => opener.current?.focus({ preventScroll: true }));
|
|
284
|
+
};
|
|
285
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
286
|
+
/* @__PURE__ */ jsx("div", { className: "scui-message-images", "aria-label": "Message images", children: items.map((item, index) => item.url ? /* @__PURE__ */ jsx("button", { type: "button", "aria-label": `View image ${item.label}`, onClick: (event) => {
|
|
287
|
+
opener.current = event.currentTarget;
|
|
288
|
+
setActive(viewable.indexOf(item));
|
|
289
|
+
}, children: /* @__PURE__ */ jsx("img", { src: item.url, alt: "" }) }, item.id ?? `${item.label}:${index}`) : item.reference && adapter?.resolveImage ? /* @__PURE__ */ jsxs("button", { type: "button", "data-lazy": "true", "aria-label": `Load image ${item.label}`, onClick: (event) => {
|
|
290
|
+
opener.current = event.currentTarget;
|
|
291
|
+
setActive(viewable.indexOf(item));
|
|
292
|
+
}, children: [
|
|
293
|
+
/* @__PURE__ */ jsx(UiIcon, { name: "image", size: 16 }),
|
|
294
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
295
|
+
/* @__PURE__ */ jsx("strong", { children: item.label }),
|
|
296
|
+
/* @__PURE__ */ jsx("small", { children: "Load preview" })
|
|
297
|
+
] })
|
|
298
|
+
] }, item.id ?? `${item.label}:${index}`) : /* @__PURE__ */ jsxs("span", { "data-unavailable": "true", children: [
|
|
299
|
+
/* @__PURE__ */ jsx(UiIcon, { name: "image", size: 14 }),
|
|
300
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
301
|
+
/* @__PURE__ */ jsx("strong", { children: item.label }),
|
|
302
|
+
/* @__PURE__ */ jsx("small", { children: "Preview unavailable" })
|
|
303
|
+
] })
|
|
304
|
+
] }, item.id ?? `${item.label}:${index}`)) }),
|
|
305
|
+
active !== null && viewable[active] ? /* @__PURE__ */ jsx(ImageViewer, { items: viewable, index: active, adapter, onChange: setActive, onClose: close }) : null
|
|
306
|
+
] });
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
export {
|
|
310
|
+
uiMemory,
|
|
311
|
+
resetSupercodeUiMemory,
|
|
312
|
+
boundedSet,
|
|
313
|
+
MAX_CONTEXT_ITEMS,
|
|
314
|
+
MAX_IMAGE_ITEMS,
|
|
315
|
+
normalizeContext,
|
|
316
|
+
mergeContext,
|
|
317
|
+
normalizeImages,
|
|
318
|
+
mergeImages,
|
|
319
|
+
partitionAttachments,
|
|
320
|
+
normalizeAttachmentCandidates,
|
|
321
|
+
ContextCandidate,
|
|
322
|
+
ContextCandidates,
|
|
323
|
+
imageAttachmentsFromFiles,
|
|
324
|
+
ContextTray,
|
|
325
|
+
ImageTray,
|
|
326
|
+
ImageViewer,
|
|
327
|
+
MessageImages
|
|
328
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import {
|
|
2
|
+
HarnessLogo
|
|
3
|
+
} from "./chunk-ATCOWFRV.mjs";
|
|
4
|
+
import {
|
|
5
|
+
projectAgentActivity
|
|
6
|
+
} from "./chunk-LS6JBXNT.mjs";
|
|
7
|
+
|
|
8
|
+
// src/activity.jsx
|
|
9
|
+
import { jsx, jsxs } from "preact/jsx-runtime";
|
|
10
|
+
function AgentActivityLauncher({ state, onOpen, class: className = "", showSummary = false, components = {} }) {
|
|
11
|
+
const value = projectAgentActivity(state);
|
|
12
|
+
const Logo = components.HarnessLogo ?? HarnessLogo;
|
|
13
|
+
const badge = value.unreadCount > 99 ? "99+" : String(value.unreadCount);
|
|
14
|
+
const label = [value.title, value.detail, value.unreadCount ? `${value.unreadCount} unread` : ""].filter(Boolean).join(" \xB7 ");
|
|
15
|
+
return /* @__PURE__ */ jsxs("button", { className: `scui-launcher ${className}`, "data-activity": value.activity, "data-unread-tone": value.unreadTone, type: "button", "aria-label": `Open ${label}`, onClick: () => onOpen?.(value), children: [
|
|
16
|
+
/* @__PURE__ */ jsxs("span", { className: "scui-launcher-logo", children: [
|
|
17
|
+
/* @__PURE__ */ jsx(Logo, { id: value.harness || "supercode", activity: value.activity, size: 36 }),
|
|
18
|
+
value.unreadCount ? /* @__PURE__ */ jsx("b", { "aria-hidden": "true", children: badge }) : null
|
|
19
|
+
] }),
|
|
20
|
+
showSummary ? /* @__PURE__ */ jsxs("span", { className: "scui-launcher-copy", children: [
|
|
21
|
+
/* @__PURE__ */ jsx("strong", { children: value.title }),
|
|
22
|
+
/* @__PURE__ */ jsx("small", { children: value.detail })
|
|
23
|
+
] }) : null
|
|
24
|
+
] });
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export {
|
|
28
|
+
AgentActivityLauncher
|
|
29
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// src/icon.jsx
|
|
2
|
+
import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
|
|
3
|
+
var ICONS = {
|
|
4
|
+
agents: () => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5
|
+
/* @__PURE__ */ jsx("circle", { cx: "6", cy: "6.5", r: "2" }),
|
|
6
|
+
/* @__PURE__ */ jsx("path", { d: "M2.75 13c.45-2 1.55-3 3.25-3s2.8 1 3.25 3" }),
|
|
7
|
+
/* @__PURE__ */ jsx("circle", { cx: "12.25", cy: "7", r: "1.5" }),
|
|
8
|
+
/* @__PURE__ */ jsx("path", { d: "M10.5 10.75c1.95-.65 3.45.1 4 2.25" })
|
|
9
|
+
] }),
|
|
10
|
+
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" }),
|
|
11
|
+
back: () => /* @__PURE__ */ jsx("path", { d: "m11.5 4.5-4.5 4.5 4.5 4.5" }),
|
|
12
|
+
check: () => /* @__PURE__ */ jsx("path", { d: "m4 9 3.25 3.25L14 5.5" }),
|
|
13
|
+
chevron: () => /* @__PURE__ */ jsx("path", { d: "m7 4.5 4.5 4.5L7 13.5" }),
|
|
14
|
+
close: () => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
15
|
+
/* @__PURE__ */ jsx("path", { d: "m4.75 4.75 8.5 8.5" }),
|
|
16
|
+
/* @__PURE__ */ jsx("path", { d: "m13.25 4.75-8.5 8.5" })
|
|
17
|
+
] }),
|
|
18
|
+
compose: () => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
19
|
+
/* @__PURE__ */ jsx("path", { d: "M11.75 3.75 14.25 6.25 7 13.5l-3.25.75.75-3.25 7.25-7.25Z" }),
|
|
20
|
+
/* @__PURE__ */ jsx("path", { d: "m10.5 5 2.5 2.5" })
|
|
21
|
+
] }),
|
|
22
|
+
copy: () => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
23
|
+
/* @__PURE__ */ jsx("rect", { x: "5", y: "5", width: "8", height: "8", rx: "1.5" }),
|
|
24
|
+
/* @__PURE__ */ jsx("path", { d: "M3 10.5V4.25C3 3.56 3.56 3 4.25 3h6.25" })
|
|
25
|
+
] }),
|
|
26
|
+
down: () => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
27
|
+
/* @__PURE__ */ jsx("path", { d: "M9 3.5v10" }),
|
|
28
|
+
/* @__PURE__ */ jsx("path", { d: "m4.75 9.5 4.25 4 4.25-4" })
|
|
29
|
+
] }),
|
|
30
|
+
image: () => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
31
|
+
/* @__PURE__ */ jsx("rect", { x: "3", y: "3.5", width: "12", height: "11", rx: "1.75" }),
|
|
32
|
+
/* @__PURE__ */ jsx("circle", { cx: "6.5", cy: "7", r: "1.25" }),
|
|
33
|
+
/* @__PURE__ */ jsx("path", { d: "m4.5 13 3.25-3 2.1 1.85 1.65-1.5L14 13" })
|
|
34
|
+
] }),
|
|
35
|
+
menu: () => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
36
|
+
/* @__PURE__ */ jsx("circle", { cx: "4", cy: "9", r: "1.25", fill: "currentColor", stroke: "none" }),
|
|
37
|
+
/* @__PURE__ */ jsx("circle", { cx: "9", cy: "9", r: "1.25", fill: "currentColor", stroke: "none" }),
|
|
38
|
+
/* @__PURE__ */ jsx("circle", { cx: "14", cy: "9", r: "1.25", fill: "currentColor", stroke: "none" })
|
|
39
|
+
] }),
|
|
40
|
+
plus: () => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
41
|
+
/* @__PURE__ */ jsx("path", { d: "M9 3.5v11" }),
|
|
42
|
+
/* @__PURE__ */ jsx("path", { d: "M3.5 9h11" })
|
|
43
|
+
] }),
|
|
44
|
+
search: () => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
45
|
+
/* @__PURE__ */ jsx("circle", { cx: "7.75", cy: "7.75", r: "4.25" }),
|
|
46
|
+
/* @__PURE__ */ jsx("path", { d: "m11 11 3.5 3.5" })
|
|
47
|
+
] }),
|
|
48
|
+
send: () => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
49
|
+
/* @__PURE__ */ jsx("path", { d: "M9 14.5v-11" }),
|
|
50
|
+
/* @__PURE__ */ jsx("path", { d: "m4.75 7.75 4.25-4.25 4.25 4.25" })
|
|
51
|
+
] }),
|
|
52
|
+
stop: () => /* @__PURE__ */ jsx("rect", { x: "4.5", y: "4.5", width: "9", height: "9", rx: "1.5", fill: "currentColor", stroke: "none" })
|
|
53
|
+
};
|
|
54
|
+
function UiIcon({ name, size = 16, class: className = "" }) {
|
|
55
|
+
const Glyph = ICONS[name];
|
|
56
|
+
if (!Glyph) return null;
|
|
57
|
+
return /* @__PURE__ */ jsx("svg", { className: `scui-icon ${className}`, style: { "--scui-icon-size": `${size}px` }, viewBox: "0 0 18 18", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx(Glyph, {}) });
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export {
|
|
61
|
+
UiIcon
|
|
62
|
+
};
|
package/components.d.ts
CHANGED
|
@@ -29,3 +29,6 @@ export {
|
|
|
29
29
|
|
|
30
30
|
/** Clear all session-scoped UI memory stores (drafts, queues, view choices). */
|
|
31
31
|
export declare function resetSupercodeUiMemory(): void;
|
|
32
|
+
|
|
33
|
+
export { MessengerProvider, useMessenger, MessengerSessions, MessengerContent } from './index.js';
|
|
34
|
+
export type { MessengerStarterOptions, MessengerContextValue } from './index.js';
|