@volter-ai-dev/supercode-ui 0.1.17 → 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 +503 -354
- package/composer.mjs +104 -33
- package/controller.mjs +7 -2
- package/conversation.mjs +74 -18
- package/core.mjs +64 -11
- package/embed.mjs +505 -356
- package/icon.mjs +1 -0
- package/index.d.ts +7 -4
- package/messenger.mjs +503 -354
- package/package.json +1 -1
- package/sessions.mjs +3 -2
- package/styles.css +4 -1
package/embed.mjs
CHANGED
|
@@ -119,6 +119,12 @@ function sourceString(source, keys) {
|
|
|
119
119
|
const match = new RegExp(`(?:^|[,{\\s])["']?(?:${names})["']?\\s*:\\s*("(?:\\\\.|[^"\\\\])*"|'(?:\\\\.|[^'\\\\])*'|\`(?:\\\\.|[^\`\\\\])*\`)`).exec(source);
|
|
120
120
|
return decodedLiteral(match?.[1]);
|
|
121
121
|
}
|
|
122
|
+
function assignedString(source, keys) {
|
|
123
|
+
if (!source) return "";
|
|
124
|
+
const names = keys.join("|");
|
|
125
|
+
const match = new RegExp(`\\b(?:${names})\\s*=\\s*("(?:\\\\.|[^"\\\\])*"|'(?:\\\\.|[^'\\\\])*'|\`(?:\\\\.|[^\`\\\\])*\`)`).exec(source);
|
|
126
|
+
return decodedLiteral(match?.[1]);
|
|
127
|
+
}
|
|
122
128
|
function callArgumentSource(source, open) {
|
|
123
129
|
let depth = 1;
|
|
124
130
|
let quote = "";
|
|
@@ -260,6 +266,13 @@ function planItems(args) {
|
|
|
260
266
|
return [{ label: boundedString(label, 300), status: firstString(value, ["status"]) }];
|
|
261
267
|
}).slice(0, 12);
|
|
262
268
|
}
|
|
269
|
+
function agentItems(name, resultText) {
|
|
270
|
+
if (!/list.?agents/i.test(name)) return [];
|
|
271
|
+
return (resultText ?? "").split("\n").flatMap((line) => {
|
|
272
|
+
const parts = line.trim().split(/\s+·\s+/).filter(Boolean);
|
|
273
|
+
return parts.length > 1 ? [{ label: boundedString(parts[0], 120), status: boundedString(parts.slice(1).join(" \xB7 "), 180) }] : [];
|
|
274
|
+
}).slice(0, 12);
|
|
275
|
+
}
|
|
263
276
|
function editPreview(args, resultText, source) {
|
|
264
277
|
const direct = firstString(args, ["patch", "diff"]);
|
|
265
278
|
if (direct) return direct;
|
|
@@ -277,7 +290,19 @@ function editPreview(args, resultText, source) {
|
|
|
277
290
|
}
|
|
278
291
|
function toolResultEnvelope(resultText) {
|
|
279
292
|
const match = /^Script (?:completed|failed)\r?\nWall time ([0-9.]+) seconds\r?\nOutput:\r?\n([\s\S]*)$/.exec(resultText ?? "");
|
|
280
|
-
if (!match)
|
|
293
|
+
if (!match) {
|
|
294
|
+
try {
|
|
295
|
+
const value = JSON.parse(resultText ?? "");
|
|
296
|
+
const object = record(value);
|
|
297
|
+
return {
|
|
298
|
+
preview: typeof value === "string" ? value : firstString(object, ["output", "message", "text", "summary", "result"]) || resultText || "",
|
|
299
|
+
value: object,
|
|
300
|
+
durationMs: null
|
|
301
|
+
};
|
|
302
|
+
} catch {
|
|
303
|
+
return { preview: resultText ?? "", value: null, durationMs: null };
|
|
304
|
+
}
|
|
305
|
+
}
|
|
281
306
|
const durationMs = Number(match[1]) * 1e3;
|
|
282
307
|
try {
|
|
283
308
|
const value = record(JSON.parse(match[2]));
|
|
@@ -290,6 +315,15 @@ function toolResultEnvelope(resultText) {
|
|
|
290
315
|
return { preview: match[2], value: null, durationMs: Number.isFinite(durationMs) ? durationMs : null };
|
|
291
316
|
}
|
|
292
317
|
}
|
|
318
|
+
function semanticAgentPreview(name, status, outcome) {
|
|
319
|
+
const normalized = name.toLocaleLowerCase();
|
|
320
|
+
if (status === "error") return outcome.preview;
|
|
321
|
+
if (/^(?:agent|task)$|spawn.?agent/.test(normalized) && outcome.preview) return "Agent is working in the background.";
|
|
322
|
+
if (/send.?message|followup.?task/.test(normalized) && outcome.preview) {
|
|
323
|
+
return /resumed from transcript|resumedAgentId/i.test(outcome.preview) ? "Agent resumed in the background." : "Message delivered.";
|
|
324
|
+
}
|
|
325
|
+
return outcome.preview;
|
|
326
|
+
}
|
|
293
327
|
function verificationCommand(command) {
|
|
294
328
|
let shell = "";
|
|
295
329
|
let quote = "";
|
|
@@ -322,12 +356,13 @@ function verificationCommand(command) {
|
|
|
322
356
|
function classifyTool(name, command) {
|
|
323
357
|
const normalized = name.toLocaleLowerCase();
|
|
324
358
|
if (/write_stdin|^wait$/.test(normalized)) return "command";
|
|
325
|
-
if (/update.?plan|todo|checklist|taskcreate|taskupdate/.test(normalized)) return "plan";
|
|
359
|
+
if (/update.?plan|todo|checklist|taskcreate|taskupdate|create.?goal|update.?goal/.test(normalized)) return "plan";
|
|
326
360
|
if (/search.?replace|edit|write|patch|replace|create_file|apply_patch/.test(normalized)) return "edit";
|
|
327
361
|
if (/read|view|open_file|list_dir/.test(normalized)) return "read";
|
|
362
|
+
if (/web.?search|web.?fetch|fetch.?url/.test(normalized)) return "web";
|
|
328
363
|
if (/search|find|grep|glob|toolsearch/.test(normalized)) return "search";
|
|
329
364
|
if (/browser|web|fetch|url/.test(normalized)) return "web";
|
|
330
|
-
if (/agent|subagent|
|
|
365
|
+
if (/agent|subagent|send.?message|delegate|followup.?task|taskstop|taskoutput|^task$/.test(normalized)) return "agent";
|
|
331
366
|
if (/test|typecheck|lint|build/.test(normalized)) return "test";
|
|
332
367
|
if (/terminal|bash|shell|command|exec|write_stdin|^wait$/.test(normalized)) return verificationCommand(command) ? "test" : "command";
|
|
333
368
|
return "other";
|
|
@@ -336,9 +371,17 @@ function toolAction(status, category, name, tools) {
|
|
|
336
371
|
const position = status === "pending" ? 0 : status === "error" ? 2 : 1;
|
|
337
372
|
if (tools.length > 1) return [`Running ${tools.length} actions`, `Ran ${tools.length} actions`, `${tools.length} actions failed`][position];
|
|
338
373
|
const normalized = name.toLocaleLowerCase();
|
|
339
|
-
if (/
|
|
340
|
-
if (/kill_command_or_subagent/.test(normalized)) return ["Stopping", "Stopped", "Stop failed"][position];
|
|
374
|
+
if (/send.?message|followup.?task/.test(normalized)) return ["Messaging agent", "Messaged agent", "Agent message failed"][position];
|
|
375
|
+
if (/taskstop|interrupt.?agent|kill_command_or_subagent/.test(normalized)) return ["Stopping agent", "Stopped agent", "Stop failed"][position];
|
|
376
|
+
if (/list.?agents|taskoutput|wait.?agent/.test(normalized)) return ["Checking agents", "Checked agents", "Agent check failed"][position];
|
|
341
377
|
if (/get_command_or_subagent_output|write_stdin|^wait$/.test(normalized)) return ["Waiting for", "Checked", "Check failed"][position];
|
|
378
|
+
if (/web.?search/.test(normalized)) return ["Searching web", "Searched web", "Web search failed"][position];
|
|
379
|
+
if (/web.?fetch|fetch.?url/.test(normalized)) return ["Fetching page", "Fetched page", "Page fetch failed"][position];
|
|
380
|
+
if (/^skill$|use.?skill|load.?skill/.test(normalized)) return ["Loading skill", "Loaded skill", "Skill load failed"][position];
|
|
381
|
+
if (/taskcreate/.test(normalized)) return ["Adding task", "Added task", "Task creation failed"][position];
|
|
382
|
+
if (/taskupdate/.test(normalized)) return ["Updating task", "Updated task", "Task update failed"][position];
|
|
383
|
+
if (/create.?goal/.test(normalized)) return ["Creating goal", "Created goal", "Goal creation failed"][position];
|
|
384
|
+
if (/update.?goal/.test(normalized)) return ["Updating goal", "Updated goal", "Goal update failed"][position];
|
|
342
385
|
const actions = {
|
|
343
386
|
read: ["Reading", "Read", "Read failed"],
|
|
344
387
|
search: ["Searching", "Searched", "Search failed"],
|
|
@@ -355,18 +398,21 @@ function createToolPresentation(entry) {
|
|
|
355
398
|
const envelope = toolEnvelope(entry);
|
|
356
399
|
const args = envelope.args;
|
|
357
400
|
const outcome = toolResultEnvelope(entry.resultText);
|
|
401
|
+
const patchSource = assignedString(envelope.source, ["patch"]) || envelope.source;
|
|
358
402
|
const command = firstString(args, ["command", "cmd"]) || sourceString(envelope.callSource, ["command", "cmd"]);
|
|
359
403
|
const category = classifyTool(envelope.name, command || envelope.source || entry.arguments || "");
|
|
360
|
-
const path = firstString(args, ["file_path", "target_file", "target_directory", "path"]) || sourceString(envelope.callSource, ["file_path", "target_file", "target_directory", "path"]) || patchPath(
|
|
404
|
+
const path = firstString(args, ["file_path", "target_file", "target_directory", "path"]) || sourceString(envelope.callSource, ["file_path", "target_file", "target_directory", "path"]) || patchPath(patchSource);
|
|
361
405
|
const query = firstString(args, ["query", "pattern"]) || sourceString(envelope.callSource, ["query", "pattern", "q"]);
|
|
362
406
|
const url = firstString(args, ["url"]) || sourceString(envelope.callSource, ["url", "ref_id"]);
|
|
363
|
-
const subject = firstString(args, ["subject", "description", "summary", "task", "prompt"]) || sourceString(envelope.callSource, ["subject", "description", "summary", "task", "prompt"]);
|
|
407
|
+
const subject = firstString(args, ["subject", "description", "summary", "task", "objective", "prompt"]) || sourceString(envelope.callSource, ["subject", "description", "summary", "task", "objective", "prompt"]);
|
|
408
|
+
const agentTarget = category === "agent" ? firstString(record(outcome.value), ["command", "name"]) || firstString(args, ["target", "task_name", "taskId", "task_id", "agentId", "agent_id", "resume", "team_name"]) || sourceString(envelope.callSource, ["target", "task_name", "taskId", "task_id", "agentId", "agent_id", "resume", "team_name"]) : "";
|
|
409
|
+
const skillTarget = /^skill$|use.?skill|load.?skill/i.test(envelope.name) ? firstString(args, ["skill", "name"]) || sourceString(envelope.callSource, ["skill", "name"]) : "";
|
|
364
410
|
const background = /get_command_or_subagent_output|kill_command_or_subagent/i.test(envelope.name) ? "background task" : /write_stdin|^wait$/i.test(envelope.name) ? "background command" : "";
|
|
365
|
-
const items = planItems(args);
|
|
411
|
+
const items = category === "agent" ? agentItems(envelope.name, outcome.preview) : planItems(args);
|
|
366
412
|
const taskId = firstString(args, ["taskId", "task_id"]);
|
|
367
413
|
const planTarget = category === "plan" ? items.length ? `${items.length} ${items.length === 1 ? "item" : "items"}` : taskId ? `task ${taskId}` : "" : "";
|
|
368
|
-
const target = path || command || query || url || subject || background || planTarget || (envelope.tools.length > 1 ? `${envelope.tools.length} coordinated actions` : toolTarget(entry.arguments));
|
|
369
|
-
const previewSource = category === "edit" ? editPreview(args, outcome.preview, envelope.
|
|
414
|
+
const target = path || command || query || url || subject || agentTarget || skillTarget || background || planTarget || (envelope.tools.length > 1 ? `${envelope.tools.length} coordinated actions` : toolTarget(entry.arguments));
|
|
415
|
+
const previewSource = category === "edit" ? editPreview(args, outcome.preview, patchSource) : category === "agent" ? semanticAgentPreview(envelope.name, entry.status ?? "completed", outcome) : outcome.preview;
|
|
370
416
|
const result = record(entry.resultContent);
|
|
371
417
|
const metadata = record(entry.metadata);
|
|
372
418
|
const resultMetadata = record(result?.metadata);
|
|
@@ -638,7 +684,7 @@ function sessionActivity(state, row) {
|
|
|
638
684
|
function filterSessions(rows, query) {
|
|
639
685
|
const needle = query.trim().toLocaleLowerCase();
|
|
640
686
|
if (!needle) return [...rows];
|
|
641
|
-
return rows.filter((row) => [row.name, row.title, row.cwd, row.harness, harnessDisplayName(row.harness)].some((value) => value.toLocaleLowerCase().includes(needle)));
|
|
687
|
+
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)));
|
|
642
688
|
}
|
|
643
689
|
function groupConversation(entries) {
|
|
644
690
|
const blocks = [];
|
|
@@ -718,6 +764,7 @@ function boundedSet(map, key, value) {
|
|
|
718
764
|
// src/icon.jsx
|
|
719
765
|
import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
|
|
720
766
|
var ICONS = {
|
|
767
|
+
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" }),
|
|
721
768
|
back: () => /* @__PURE__ */ jsx("path", { d: "m11.5 4.5-4.5 4.5 4.5 4.5" }),
|
|
722
769
|
check: () => /* @__PURE__ */ jsx("path", { d: "m4 9 3.25 3.25L14 5.5" }),
|
|
723
770
|
chevron: () => /* @__PURE__ */ jsx("path", { d: "m7 4.5 4.5 4.5L7 13.5" }),
|
|
@@ -758,6 +805,44 @@ function UiIcon({ name, size = 16, class: className = "" }) {
|
|
|
758
805
|
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, {}) });
|
|
759
806
|
}
|
|
760
807
|
|
|
808
|
+
// src/context.jsx
|
|
809
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "preact/jsx-runtime";
|
|
810
|
+
var MAX_CONTEXT_ITEMS = 32;
|
|
811
|
+
function normalizeContext(value) {
|
|
812
|
+
return (Array.isArray(value) ? value : value ? [value] : []).flatMap((item) => {
|
|
813
|
+
if (!item || typeof item.label !== "string" || typeof item.detail !== "string") return [];
|
|
814
|
+
const label = item.label.trim().slice(0, 200);
|
|
815
|
+
const detail = item.detail.slice(0, 2e4);
|
|
816
|
+
if (!label || !detail) return [];
|
|
817
|
+
return [{
|
|
818
|
+
...typeof item.id === "string" && item.id ? { id: item.id.slice(0, 2e3) } : {},
|
|
819
|
+
...typeof item.kind === "string" && item.kind ? { kind: item.kind.slice(0, 100) } : {},
|
|
820
|
+
label,
|
|
821
|
+
detail
|
|
822
|
+
}];
|
|
823
|
+
}).slice(0, MAX_CONTEXT_ITEMS);
|
|
824
|
+
}
|
|
825
|
+
function mergeContext(current, picked) {
|
|
826
|
+
const next = [...current];
|
|
827
|
+
const seen = new Set(current.map((item) => item.id ? `id:${item.id}` : `value:${item.kind ?? ""}\0${item.label}\0${item.detail}`));
|
|
828
|
+
for (const item of normalizeContext(picked)) {
|
|
829
|
+
const key = item.id ? `id:${item.id}` : `value:${item.kind ?? ""}\0${item.label}\0${item.detail}`;
|
|
830
|
+
if (seen.has(key)) continue;
|
|
831
|
+
seen.add(key);
|
|
832
|
+
next.push(item);
|
|
833
|
+
if (next.length === MAX_CONTEXT_ITEMS) break;
|
|
834
|
+
}
|
|
835
|
+
return next;
|
|
836
|
+
}
|
|
837
|
+
function ContextTray({ items, onRemove }) {
|
|
838
|
+
if (!items.length) return null;
|
|
839
|
+
return /* @__PURE__ */ jsx2("div", { class: "scui-compose-context", "aria-label": "Attached context", children: items.map((item, index) => /* @__PURE__ */ jsxs2("span", { children: [
|
|
840
|
+
/* @__PURE__ */ jsx2(UiIcon, { name: "attach", size: 12 }),
|
|
841
|
+
/* @__PURE__ */ jsx2("strong", { children: item.label }),
|
|
842
|
+
/* @__PURE__ */ jsx2("button", { type: "button", "aria-label": `Remove context ${item.label}`, onClick: () => onRemove(index), children: /* @__PURE__ */ jsx2(UiIcon, { name: "close", size: 12 }) })
|
|
843
|
+
] }, item.id ?? `${item.label}:${index}`)) });
|
|
844
|
+
}
|
|
845
|
+
|
|
761
846
|
// src/textarea.js
|
|
762
847
|
import { useLayoutEffect } from "preact/hooks";
|
|
763
848
|
function useAutosizeTextarea(ref, value) {
|
|
@@ -773,7 +858,7 @@ function useAutosizeTextarea(ref, value) {
|
|
|
773
858
|
}
|
|
774
859
|
|
|
775
860
|
// src/composer.jsx
|
|
776
|
-
import { jsx as
|
|
861
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "preact/jsx-runtime";
|
|
777
862
|
var composerMemory = /* @__PURE__ */ new Map();
|
|
778
863
|
function ContinuationBar({ state, adapter, labels = DEFAULT_LABELS }) {
|
|
779
864
|
if (state.mode !== "mirror" || state.canSend) return null;
|
|
@@ -783,29 +868,32 @@ function ContinuationBar({ state, adapter, labels = DEFAULT_LABELS }) {
|
|
|
783
868
|
const resume = canContinueHere(state);
|
|
784
869
|
const join = state.canAttach;
|
|
785
870
|
const branch = state.canBranch;
|
|
786
|
-
if (!resume && !join && !branch) return /* @__PURE__ */
|
|
787
|
-
/* @__PURE__ */
|
|
788
|
-
/* @__PURE__ */
|
|
871
|
+
if (!resume && !join && !branch) return /* @__PURE__ */ jsx3("div", { class: "scui-continuation", children: /* @__PURE__ */ jsxs3("span", { children: [
|
|
872
|
+
/* @__PURE__ */ jsx3("strong", { children: activeElsewhere ? "Active elsewhere" : "Read-only" }),
|
|
873
|
+
/* @__PURE__ */ jsx3("small", { children: "This session cannot be continued by an available harness." })
|
|
789
874
|
] }) });
|
|
790
|
-
return /* @__PURE__ */
|
|
791
|
-
/* @__PURE__ */
|
|
792
|
-
/* @__PURE__ */
|
|
793
|
-
/* @__PURE__ */
|
|
875
|
+
return /* @__PURE__ */ jsxs3("div", { class: "scui-continuation", children: [
|
|
876
|
+
/* @__PURE__ */ jsxs3("span", { children: [
|
|
877
|
+
/* @__PURE__ */ jsx3("strong", { children: activeElsewhere ? "Active elsewhere" : "Read-only" }),
|
|
878
|
+
/* @__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." })
|
|
794
879
|
] }),
|
|
795
|
-
/* @__PURE__ */
|
|
880
|
+
/* @__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 })
|
|
796
881
|
] });
|
|
797
882
|
}
|
|
798
883
|
function Composer({ state, adapter, labels = DEFAULT_LABELS, memoryKey = state.attached?.key || `${state.harness}:${state.workspace}`, pendingStatus = null, restoreDraft = null, onPending, onDraftRestored }) {
|
|
799
|
-
const remembered = composerMemory.get(memoryKey) ?? { draft: state.savedDraft, queue: [] };
|
|
884
|
+
const remembered = composerMemory.get(memoryKey) ?? { draft: state.savedDraft, context: [], queue: [] };
|
|
800
885
|
const [draft, setDraft] = useState(remembered.draft);
|
|
886
|
+
const [context, setContext] = useState(remembered.context);
|
|
801
887
|
const [queue, setQueue] = useState(remembered.queue);
|
|
802
888
|
const [dispatching, setDispatching] = useState(false);
|
|
889
|
+
const [picking, setPicking] = useState(false);
|
|
890
|
+
const [pickerError, setPickerError] = useState(null);
|
|
803
891
|
const textarea = useRef(null);
|
|
804
892
|
useAutosizeTextarea(textarea, draft);
|
|
805
|
-
const remember = (nextDraft, nextQueue) => boundedSet(composerMemory, memoryKey, { draft: nextDraft, queue: nextQueue });
|
|
893
|
+
const remember = (nextDraft, nextContext, nextQueue) => boundedSet(composerMemory, memoryKey, { draft: nextDraft, context: nextContext, queue: nextQueue });
|
|
806
894
|
const updateQueue = (update) => setQueue((items) => {
|
|
807
895
|
const next = update(items);
|
|
808
|
-
remember(draft, next);
|
|
896
|
+
remember(draft, context, next);
|
|
809
897
|
return next;
|
|
810
898
|
});
|
|
811
899
|
const queueBlocked = state.busy || pendingStatus !== null || dispatching;
|
|
@@ -815,9 +903,9 @@ function Composer({ state, adapter, labels = DEFAULT_LABELS, memoryKey = state.a
|
|
|
815
903
|
const [next, ...rest] = queue;
|
|
816
904
|
setDispatching(true);
|
|
817
905
|
setQueue(rest);
|
|
818
|
-
remember(draft, rest);
|
|
819
|
-
onPending?.(next);
|
|
820
|
-
adapter.onIntent({ action: "send", text: next });
|
|
906
|
+
remember(draft, context, rest);
|
|
907
|
+
onPending?.(next.text, next.context);
|
|
908
|
+
adapter.onIntent({ action: "send", text: next.text, ...next.context.length ? { context: next.context } : {} });
|
|
821
909
|
}
|
|
822
910
|
}, [adapter, draft, memoryKey, onPending, queue, queueBlocked, state.canSend]);
|
|
823
911
|
useEffect(() => {
|
|
@@ -829,7 +917,9 @@ function Composer({ state, adapter, labels = DEFAULT_LABELS, memoryKey = state.a
|
|
|
829
917
|
useEffect(() => {
|
|
830
918
|
if (!restoreDraft) return;
|
|
831
919
|
setDraft(restoreDraft.text);
|
|
832
|
-
|
|
920
|
+
const restoredContext = normalizeContext(restoreDraft.context);
|
|
921
|
+
setContext(restoredContext);
|
|
922
|
+
remember(restoreDraft.text, restoredContext, queue);
|
|
833
923
|
textarea.current?.focus({ preventScroll: true });
|
|
834
924
|
onDraftRestored?.(restoreDraft.id);
|
|
835
925
|
}, [onDraftRestored, restoreDraft?.id]);
|
|
@@ -837,43 +927,70 @@ function Composer({ state, adapter, labels = DEFAULT_LABELS, memoryKey = state.a
|
|
|
837
927
|
const timer = setTimeout(() => adapter.onIntent({ action: "draft", text: draft }), 250);
|
|
838
928
|
return () => clearTimeout(timer);
|
|
839
929
|
}, [adapter, draft]);
|
|
930
|
+
const pickContext = () => {
|
|
931
|
+
if (!adapter.pickContext || state.mode !== "control" || picking || context.length >= MAX_CONTEXT_ITEMS) return;
|
|
932
|
+
setPicking(true);
|
|
933
|
+
setPickerError(null);
|
|
934
|
+
Promise.resolve().then(() => adapter.pickContext()).then((picked) => {
|
|
935
|
+
setContext((current) => {
|
|
936
|
+
const next = mergeContext(current, picked);
|
|
937
|
+
remember(draft, next, queue);
|
|
938
|
+
return next;
|
|
939
|
+
});
|
|
940
|
+
}, (error) => setPickerError(error instanceof Error ? error.message : "Could not attach context.")).finally(() => setPicking(false));
|
|
941
|
+
};
|
|
840
942
|
const send = () => {
|
|
841
943
|
const text = draft.trim();
|
|
842
944
|
if (!text) return;
|
|
843
|
-
|
|
945
|
+
const message = { text, context };
|
|
946
|
+
if (queuesNewMessage) updateQueue((items) => [...items, message]);
|
|
844
947
|
else if (state.canSend) {
|
|
845
948
|
if (onPending) setDispatching(true);
|
|
846
|
-
onPending?.(text);
|
|
847
|
-
adapter.onIntent({ action: "send", text });
|
|
949
|
+
onPending?.(text, context);
|
|
950
|
+
adapter.onIntent({ action: "send", text, ...context.length ? { context } : {} });
|
|
848
951
|
} else return;
|
|
849
952
|
setDraft("");
|
|
850
|
-
|
|
953
|
+
setContext([]);
|
|
954
|
+
remember("", [], queuesNewMessage ? [...queue, message] : queue);
|
|
851
955
|
};
|
|
852
|
-
return /* @__PURE__ */
|
|
853
|
-
queue.length ? /* @__PURE__ */
|
|
854
|
-
/* @__PURE__ */
|
|
956
|
+
return /* @__PURE__ */ jsxs3("div", { class: "scui-compose", children: [
|
|
957
|
+
queue.length ? /* @__PURE__ */ jsxs3("div", { class: "scui-queue", children: [
|
|
958
|
+
/* @__PURE__ */ jsxs3("strong", { children: [
|
|
855
959
|
queue.length,
|
|
856
960
|
" queued"
|
|
857
961
|
] }),
|
|
858
|
-
queue.map((item, index) => /* @__PURE__ */
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
962
|
+
queue.map((item, index) => /* @__PURE__ */ jsxs3("span", { children: [
|
|
963
|
+
/* @__PURE__ */ jsxs3("span", { children: [
|
|
964
|
+
item.text,
|
|
965
|
+
item.context.length ? /* @__PURE__ */ jsxs3("small", { children: [
|
|
966
|
+
item.context.length,
|
|
967
|
+
" attached"
|
|
968
|
+
] }) : null
|
|
969
|
+
] }),
|
|
970
|
+
/* @__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 }) })
|
|
971
|
+
] }, `${index}:${item.text}`))
|
|
862
972
|
] }) : null,
|
|
863
|
-
/* @__PURE__ */
|
|
864
|
-
|
|
973
|
+
/* @__PURE__ */ jsx3(ContextTray, { items: context, onRemove: (index) => setContext((items) => {
|
|
974
|
+
const next = items.filter((_, itemIndex) => itemIndex !== index);
|
|
975
|
+
remember(draft, next, queue);
|
|
976
|
+
return next;
|
|
977
|
+
}) }),
|
|
978
|
+
pickerError ? /* @__PURE__ */ jsx3("small", { class: "scui-context-error", role: "alert", children: pickerError }) : null,
|
|
979
|
+
/* @__PURE__ */ jsxs3("div", { class: "scui-envelope", children: [
|
|
980
|
+
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,
|
|
981
|
+
/* @__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) => {
|
|
865
982
|
const value = event.currentTarget.value;
|
|
866
983
|
setDraft(value);
|
|
867
|
-
remember(value, queue);
|
|
984
|
+
remember(value, context, queue);
|
|
868
985
|
}, onKeyDown: (event) => {
|
|
869
986
|
if (isSendKey(event)) {
|
|
870
987
|
event.preventDefault();
|
|
871
988
|
send();
|
|
872
989
|
}
|
|
873
990
|
} }),
|
|
874
|
-
/* @__PURE__ */
|
|
875
|
-
state.busy ? /* @__PURE__ */
|
|
876
|
-
/* @__PURE__ */
|
|
991
|
+
/* @__PURE__ */ jsxs3("span", { children: [
|
|
992
|
+
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,
|
|
993
|
+
/* @__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 }) })
|
|
877
994
|
] })
|
|
878
995
|
] })
|
|
879
996
|
] });
|
|
@@ -886,7 +1003,7 @@ import { useEffect as useEffect3, useId, useLayoutEffect as useLayoutEffect2, us
|
|
|
886
1003
|
// src/markdown.jsx
|
|
887
1004
|
import MarkdownIt from "markdown-it";
|
|
888
1005
|
import { useEffect as useEffect2, useMemo, useRef as useRef2 } from "preact/hooks";
|
|
889
|
-
import { jsx as
|
|
1006
|
+
import { jsx as jsx4 } from "preact/jsx-runtime";
|
|
890
1007
|
var markdown = new MarkdownIt({ html: false, linkify: true, breaks: false });
|
|
891
1008
|
var LANGUAGE_LABELS = {
|
|
892
1009
|
bash: "Shell",
|
|
@@ -973,11 +1090,11 @@ function Markdown({ value, copyText }) {
|
|
|
973
1090
|
}, 1500);
|
|
974
1091
|
resets.current.set(button, timer);
|
|
975
1092
|
};
|
|
976
|
-
return /* @__PURE__ */
|
|
1093
|
+
return /* @__PURE__ */ jsx4("div", { class: "scui-markdown", "data-copyable": Boolean(copyText), onClick: copyCode, dangerouslySetInnerHTML: { __html: html } });
|
|
977
1094
|
}
|
|
978
1095
|
|
|
979
1096
|
// src/conversation.jsx
|
|
980
|
-
import { Fragment as Fragment3, jsx as
|
|
1097
|
+
import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs4 } from "preact/jsx-runtime";
|
|
981
1098
|
function LoadingStatus({ state, compact = false }) {
|
|
982
1099
|
const copy = {
|
|
983
1100
|
connecting: ["Connecting to coding agents", "Checking installed harnesses and capabilities.", 0],
|
|
@@ -985,43 +1102,43 @@ function LoadingStatus({ state, compact = false }) {
|
|
|
985
1102
|
discovering: ["Loading recent sessions", "Scanning native session stores without loading full transcripts.", 2],
|
|
986
1103
|
ready: ["Ready", "Coding sessions are up to date.", 3]
|
|
987
1104
|
}[state.startup];
|
|
988
|
-
return /* @__PURE__ */
|
|
989
|
-
/* @__PURE__ */
|
|
990
|
-
/* @__PURE__ */
|
|
991
|
-
/* @__PURE__ */
|
|
992
|
-
/* @__PURE__ */
|
|
1105
|
+
return /* @__PURE__ */ jsxs4("div", { class: `scui-loading${compact ? " scui-loading-compact" : ""}`, role: "status", "aria-busy": state.startup !== "ready", children: [
|
|
1106
|
+
/* @__PURE__ */ jsx5("span", { class: "scui-orbit", "aria-hidden": "true", children: /* @__PURE__ */ jsx5("i", {}) }),
|
|
1107
|
+
/* @__PURE__ */ jsxs4("span", { class: "scui-loading-copy", children: [
|
|
1108
|
+
/* @__PURE__ */ jsx5("strong", { children: copy[0] }),
|
|
1109
|
+
/* @__PURE__ */ jsx5("small", { children: copy[1] })
|
|
993
1110
|
] }),
|
|
994
|
-
/* @__PURE__ */
|
|
1111
|
+
/* @__PURE__ */ jsx5("span", { class: "scui-progress", "aria-hidden": "true", children: [1, 2, 3].map((step) => /* @__PURE__ */ jsx5("i", { "data-progress": step <= copy[2] ? "done" : step === copy[2] + 1 ? "current" : "waiting" }, step)) })
|
|
995
1112
|
] });
|
|
996
1113
|
}
|
|
997
1114
|
function RequestCard({ entry, adapter, canRespond }) {
|
|
998
1115
|
const request = entry.request;
|
|
999
1116
|
if (!request) return null;
|
|
1000
1117
|
if (request.status === "responded") {
|
|
1001
|
-
return /* @__PURE__ */
|
|
1118
|
+
return /* @__PURE__ */ jsxs4("div", { class: "scui-request-done", children: [
|
|
1002
1119
|
"\u2713 Request answered \xB7 ",
|
|
1003
1120
|
request.resolution?.name ?? request.requestKind
|
|
1004
1121
|
] });
|
|
1005
1122
|
}
|
|
1006
|
-
return /* @__PURE__ */
|
|
1007
|
-
/* @__PURE__ */
|
|
1008
|
-
/* @__PURE__ */
|
|
1009
|
-
/* @__PURE__ */
|
|
1010
|
-
request.options.map((option) => /* @__PURE__ */
|
|
1011
|
-
request.cancellable ? /* @__PURE__ */
|
|
1123
|
+
return /* @__PURE__ */ jsxs4("section", { class: "scui-request", role: "alert", "aria-label": `${request.requestKind} needs input`, children: [
|
|
1124
|
+
/* @__PURE__ */ jsx5("strong", { children: "Agent needs input" }),
|
|
1125
|
+
/* @__PURE__ */ jsx5(Markdown, { value: request.payloadText || entry.text, copyText: adapter?.copyText }),
|
|
1126
|
+
/* @__PURE__ */ jsxs4("div", { class: "scui-request-actions", children: [
|
|
1127
|
+
request.options.map((option) => /* @__PURE__ */ jsx5("button", { type: "button", disabled: !canRespond, onClick: () => adapter.onIntent({ action: "respond", requestId: request.requestId, optionId: option.optionId }), children: option.name }, option.optionId)),
|
|
1128
|
+
request.cancellable ? /* @__PURE__ */ jsx5("button", { type: "button", disabled: !canRespond, onClick: () => adapter.onIntent({ action: "respond", requestId: request.requestId, optionId: null }), children: "Cancel" }) : null
|
|
1012
1129
|
] })
|
|
1013
1130
|
] });
|
|
1014
1131
|
}
|
|
1015
1132
|
function ContextDisclosure({ context }) {
|
|
1016
1133
|
if (!context?.length) return null;
|
|
1017
|
-
return /* @__PURE__ */
|
|
1018
|
-
/* @__PURE__ */
|
|
1134
|
+
return /* @__PURE__ */ jsxs4("details", { class: "scui-context", children: [
|
|
1135
|
+
/* @__PURE__ */ jsxs4("summary", { children: [
|
|
1019
1136
|
"Context \xB7 ",
|
|
1020
1137
|
context.length
|
|
1021
1138
|
] }),
|
|
1022
|
-
/* @__PURE__ */
|
|
1023
|
-
/* @__PURE__ */
|
|
1024
|
-
/* @__PURE__ */
|
|
1139
|
+
/* @__PURE__ */ jsx5("div", { children: context.map((item, index) => /* @__PURE__ */ jsxs4("p", { children: [
|
|
1140
|
+
/* @__PURE__ */ jsx5("strong", { children: item.label }),
|
|
1141
|
+
/* @__PURE__ */ jsx5("span", { children: item.detail })
|
|
1025
1142
|
] }, item.id ?? index)) })
|
|
1026
1143
|
] });
|
|
1027
1144
|
}
|
|
@@ -1043,46 +1160,46 @@ function MessageMeta({ entry, adapter }) {
|
|
|
1043
1160
|
reset.current = setTimeout(() => setCopyState2("idle"), 1500);
|
|
1044
1161
|
};
|
|
1045
1162
|
const copyLabel = copyState === "copied" ? "Message copied" : copyState === "failed" ? "Copy failed \xB7 retry" : "Copy message";
|
|
1046
|
-
return /* @__PURE__ */
|
|
1047
|
-
validDate ? /* @__PURE__ */
|
|
1048
|
-
adapter?.copyText && entry.text ? /* @__PURE__ */
|
|
1163
|
+
return /* @__PURE__ */ jsxs4("footer", { class: "scui-message-meta", children: [
|
|
1164
|
+
validDate ? /* @__PURE__ */ jsx5("time", { dateTime: validDate.toISOString(), title: validDate.toLocaleString(), children: validDate.toLocaleTimeString([], { hour: "numeric", minute: "2-digit" }) }) : null,
|
|
1165
|
+
adapter?.copyText && entry.text ? /* @__PURE__ */ jsx5("button", { type: "button", "aria-label": copyLabel, title: copyLabel, onClick: copy, "data-status": copyState, children: /* @__PURE__ */ jsx5(UiIcon, { name: "copy", size: 13 }) }) : null
|
|
1049
1166
|
] });
|
|
1050
1167
|
}
|
|
1051
1168
|
var TOOL_ICONS = {
|
|
1052
|
-
read: () => /* @__PURE__ */
|
|
1053
|
-
/* @__PURE__ */
|
|
1054
|
-
/* @__PURE__ */
|
|
1169
|
+
read: () => /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
1170
|
+
/* @__PURE__ */ jsx5("path", { d: "M5 2.75h7.25L15 5.5v7.75A1.75 1.75 0 0 1 13.25 15h-8.5A1.75 1.75 0 0 1 3 13.25v-8.5A2 2 0 0 1 5 2.75Z" }),
|
|
1171
|
+
/* @__PURE__ */ jsx5("path", { d: "M12 2.9v3h2.85M6 9h6M6 12h4" })
|
|
1055
1172
|
] }),
|
|
1056
|
-
search: () => /* @__PURE__ */
|
|
1057
|
-
/* @__PURE__ */
|
|
1058
|
-
/* @__PURE__ */
|
|
1173
|
+
search: () => /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
1174
|
+
/* @__PURE__ */ jsx5("circle", { cx: "8", cy: "8", r: "4.5" }),
|
|
1175
|
+
/* @__PURE__ */ jsx5("path", { d: "m11.5 11.5 3 3" })
|
|
1059
1176
|
] }),
|
|
1060
|
-
edit: () => /* @__PURE__ */
|
|
1061
|
-
/* @__PURE__ */
|
|
1062
|
-
/* @__PURE__ */
|
|
1177
|
+
edit: () => /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
1178
|
+
/* @__PURE__ */ jsx5("path", { d: "m11.75 3.25 3 3-8.5 8.5-3.75.75.75-3.75 8.5-8.5Z" }),
|
|
1179
|
+
/* @__PURE__ */ jsx5("path", { d: "m10 5 3 3" })
|
|
1063
1180
|
] }),
|
|
1064
|
-
command: () => /* @__PURE__ */
|
|
1065
|
-
test: () => /* @__PURE__ */
|
|
1066
|
-
/* @__PURE__ */
|
|
1067
|
-
/* @__PURE__ */
|
|
1181
|
+
command: () => /* @__PURE__ */ jsx5(Fragment3, { children: /* @__PURE__ */ jsx5("path", { d: "m3 5 3 3-3 3M8 12h6" }) }),
|
|
1182
|
+
test: () => /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
1183
|
+
/* @__PURE__ */ jsx5("path", { d: "M6 2.5v3L3 12a2 2 0 0 0 1.8 3h8.4a2 2 0 0 0 1.8-3l-3-6.5v-3M5 9h8" }),
|
|
1184
|
+
/* @__PURE__ */ jsx5("path", { d: "M5 2.5h8" })
|
|
1068
1185
|
] }),
|
|
1069
|
-
web: () => /* @__PURE__ */
|
|
1070
|
-
/* @__PURE__ */
|
|
1071
|
-
/* @__PURE__ */
|
|
1186
|
+
web: () => /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
1187
|
+
/* @__PURE__ */ jsx5("circle", { cx: "9", cy: "9", r: "6.5" }),
|
|
1188
|
+
/* @__PURE__ */ jsx5("path", { d: "M2.75 9h12.5M9 2.5c2 1.8 3 4 3 6.5s-1 4.7-3 6.5c-2-1.8-3-4-3-6.5s1-4.7 3-6.5Z" })
|
|
1072
1189
|
] }),
|
|
1073
|
-
agent: () => /* @__PURE__ */
|
|
1074
|
-
/* @__PURE__ */
|
|
1075
|
-
/* @__PURE__ */
|
|
1190
|
+
agent: () => /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
1191
|
+
/* @__PURE__ */ jsx5("circle", { cx: "9", cy: "6", r: "2.5" }),
|
|
1192
|
+
/* @__PURE__ */ jsx5("path", { d: "M4 15c.4-3 2-4.5 5-4.5s4.6 1.5 5 4.5" })
|
|
1076
1193
|
] }),
|
|
1077
|
-
plan: () => /* @__PURE__ */
|
|
1078
|
-
other: () => /* @__PURE__ */
|
|
1079
|
-
/* @__PURE__ */
|
|
1080
|
-
/* @__PURE__ */
|
|
1194
|
+
plan: () => /* @__PURE__ */ jsx5(Fragment3, { children: /* @__PURE__ */ jsx5("path", { d: "m3 5 1 1 2-2M3 9l1 1 2-2M3 13l1 1 2-2M8 5h7M8 9h7M8 13h7" }) }),
|
|
1195
|
+
other: () => /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
1196
|
+
/* @__PURE__ */ jsx5("path", { d: "M9 2.5v3M9 12.5v3M2.5 9h3M12.5 9h3" }),
|
|
1197
|
+
/* @__PURE__ */ jsx5("circle", { cx: "9", cy: "9", r: "3.5" })
|
|
1081
1198
|
] })
|
|
1082
1199
|
};
|
|
1083
1200
|
function ToolIcon({ category }) {
|
|
1084
1201
|
const Glyph = TOOL_ICONS[category] ?? TOOL_ICONS.other;
|
|
1085
|
-
return /* @__PURE__ */
|
|
1202
|
+
return /* @__PURE__ */ jsx5("svg", { class: "scui-tool-icon", viewBox: "0 0 18 18", fill: "none", stroke: "currentColor", "stroke-width": "1.35", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx5(Glyph, {}) });
|
|
1086
1203
|
}
|
|
1087
1204
|
function toolAction2(entry, category, presentation) {
|
|
1088
1205
|
if (presentation?.action) return presentation.action;
|
|
@@ -1137,7 +1254,7 @@ function ToolMetrics({ presentation }) {
|
|
|
1137
1254
|
presentation.exitCode === null ? "" : `exit ${presentation.exitCode}`,
|
|
1138
1255
|
formatDuration(presentation.durationMs)
|
|
1139
1256
|
].filter(Boolean);
|
|
1140
|
-
return metrics.length ? /* @__PURE__ */
|
|
1257
|
+
return metrics.length ? /* @__PURE__ */ jsx5("div", { class: "scui-tool-metrics", children: metrics.map((metric) => /* @__PURE__ */ jsx5("span", { children: metric }, metric)) }) : null;
|
|
1141
1258
|
}
|
|
1142
1259
|
function PendingElapsed({ now }) {
|
|
1143
1260
|
const clock = now ?? Date.now;
|
|
@@ -1147,71 +1264,74 @@ function PendingElapsed({ now }) {
|
|
|
1147
1264
|
const timer = setInterval(() => setElapsed(Math.max(0, clock() - started.current)), 1e3);
|
|
1148
1265
|
return () => clearInterval(timer);
|
|
1149
1266
|
}, [clock]);
|
|
1150
|
-
return /* @__PURE__ */
|
|
1267
|
+
return /* @__PURE__ */ jsx5("small", { class: "scui-tool-elapsed", children: elapsed < 1e3 ? "now" : formatDuration(elapsed) });
|
|
1151
1268
|
}
|
|
1152
1269
|
function LinePreview({ value, kind }) {
|
|
1153
1270
|
if (!value) return null;
|
|
1154
|
-
return /* @__PURE__ */
|
|
1271
|
+
return /* @__PURE__ */ jsx5("ol", { class: "scui-code-preview", "data-kind": kind, children: stripAnsi(value).split("\n").map((line, index) => {
|
|
1155
1272
|
const tone = kind === "diff" ? line.startsWith("+") && !line.startsWith("+++") ? "add" : line.startsWith("-") && !line.startsWith("---") ? "remove" : line.startsWith("@@") ? "hunk" : "plain" : "plain";
|
|
1156
|
-
return /* @__PURE__ */
|
|
1157
|
-
/* @__PURE__ */
|
|
1158
|
-
/* @__PURE__ */
|
|
1273
|
+
return /* @__PURE__ */ jsxs4("li", { "data-tone": tone, children: [
|
|
1274
|
+
/* @__PURE__ */ jsx5("span", { children: index + 1 }),
|
|
1275
|
+
/* @__PURE__ */ jsx5("code", { children: line || " " })
|
|
1159
1276
|
] }, index);
|
|
1160
1277
|
}) });
|
|
1161
1278
|
}
|
|
1162
1279
|
function TerminalPreview({ presentation, pending, failed }) {
|
|
1163
|
-
return /* @__PURE__ */
|
|
1164
|
-
/* @__PURE__ */
|
|
1165
|
-
/* @__PURE__ */
|
|
1166
|
-
/* @__PURE__ */
|
|
1167
|
-
/* @__PURE__ */
|
|
1168
|
-
/* @__PURE__ */
|
|
1280
|
+
return /* @__PURE__ */ jsxs4("section", { class: "scui-terminal", children: [
|
|
1281
|
+
/* @__PURE__ */ jsxs4("header", { children: [
|
|
1282
|
+
/* @__PURE__ */ jsxs4("span", { "aria-hidden": "true", children: [
|
|
1283
|
+
/* @__PURE__ */ jsx5("i", {}),
|
|
1284
|
+
/* @__PURE__ */ jsx5("i", {}),
|
|
1285
|
+
/* @__PURE__ */ jsx5("i", {})
|
|
1169
1286
|
] }),
|
|
1170
|
-
/* @__PURE__ */
|
|
1287
|
+
/* @__PURE__ */ jsx5("code", { children: presentation.command ? `$ ${presentation.command}` : "Terminal" })
|
|
1171
1288
|
] }),
|
|
1172
|
-
presentation.preview ? /* @__PURE__ */
|
|
1173
|
-
/* @__PURE__ */
|
|
1289
|
+
presentation.preview ? /* @__PURE__ */ jsx5("pre", { "data-error": failed, children: stripAnsi(presentation.preview) }) : pending ? /* @__PURE__ */ jsxs4("div", { class: "scui-terminal-wait", children: [
|
|
1290
|
+
/* @__PURE__ */ jsx5("i", {}),
|
|
1174
1291
|
" Waiting for output"
|
|
1175
|
-
] }) : /* @__PURE__ */
|
|
1292
|
+
] }) : /* @__PURE__ */ jsx5("div", { class: "scui-terminal-empty", children: "No output" })
|
|
1176
1293
|
] });
|
|
1177
1294
|
}
|
|
1178
1295
|
function SearchPreview({ presentation }) {
|
|
1179
1296
|
const lines = stripAnsi(presentation.preview).split("\n").filter(Boolean);
|
|
1180
|
-
return /* @__PURE__ */
|
|
1181
|
-
presentation.query ? /* @__PURE__ */
|
|
1182
|
-
/* @__PURE__ */
|
|
1183
|
-
/* @__PURE__ */
|
|
1297
|
+
return /* @__PURE__ */ jsxs4("section", { class: "scui-search-preview", children: [
|
|
1298
|
+
presentation.query ? /* @__PURE__ */ jsxs4("header", { children: [
|
|
1299
|
+
/* @__PURE__ */ jsx5("span", { children: "Search" }),
|
|
1300
|
+
/* @__PURE__ */ jsx5("code", { children: presentation.query })
|
|
1184
1301
|
] }) : null,
|
|
1185
|
-
lines.length ? /* @__PURE__ */
|
|
1302
|
+
lines.length ? /* @__PURE__ */ jsx5("ol", { children: lines.map((line, index) => {
|
|
1186
1303
|
const match = /^(.*?):(\d+)(?::(\d+))?:(.*)$/.exec(line);
|
|
1187
|
-
return /* @__PURE__ */
|
|
1188
|
-
/* @__PURE__ */
|
|
1189
|
-
/* @__PURE__ */
|
|
1304
|
+
return /* @__PURE__ */ jsx5("li", { children: match ? /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
1305
|
+
/* @__PURE__ */ jsx5("code", { children: match[1] }),
|
|
1306
|
+
/* @__PURE__ */ jsxs4("small", { children: [
|
|
1190
1307
|
match[2],
|
|
1191
1308
|
match[3] ? `:${match[3]}` : ""
|
|
1192
1309
|
] }),
|
|
1193
|
-
/* @__PURE__ */
|
|
1194
|
-
] }) : /* @__PURE__ */
|
|
1195
|
-
}) }) : /* @__PURE__ */
|
|
1310
|
+
/* @__PURE__ */ jsx5("span", { children: match[4] })
|
|
1311
|
+
] }) : /* @__PURE__ */ jsx5("span", { children: line }) }, index);
|
|
1312
|
+
}) }) : /* @__PURE__ */ jsx5("p", { children: "No textual results" })
|
|
1196
1313
|
] });
|
|
1197
1314
|
}
|
|
1198
1315
|
function ToolPreview({ presentation, entry }) {
|
|
1199
1316
|
const pending = entry.status === "pending";
|
|
1200
1317
|
const failed = entry.status === "error";
|
|
1201
|
-
if (presentation.detail === "terminal") return /* @__PURE__ */
|
|
1202
|
-
if (presentation.detail === "diff") return presentation.preview ? /* @__PURE__ */
|
|
1203
|
-
if (presentation.detail === "file") return presentation.preview ? /* @__PURE__ */
|
|
1204
|
-
if (presentation.detail === "matches") return /* @__PURE__ */
|
|
1205
|
-
if (presentation.detail === "web") return /* @__PURE__ */
|
|
1206
|
-
presentation.url ? /* @__PURE__ */
|
|
1207
|
-
presentation.preview ? /* @__PURE__ */
|
|
1318
|
+
if (presentation.detail === "terminal") return /* @__PURE__ */ jsx5(TerminalPreview, { presentation, pending, failed });
|
|
1319
|
+
if (presentation.detail === "diff") return presentation.preview ? /* @__PURE__ */ jsx5(LinePreview, { value: presentation.preview, kind: "diff" }) : /* @__PURE__ */ jsx5("div", { class: "scui-tool-empty", children: "Edit completed without a textual diff" });
|
|
1320
|
+
if (presentation.detail === "file") return presentation.preview ? /* @__PURE__ */ jsx5(LinePreview, { value: presentation.preview, kind: "file" }) : /* @__PURE__ */ jsx5("div", { class: "scui-tool-empty", children: "File contents were not included in this event" });
|
|
1321
|
+
if (presentation.detail === "matches") return /* @__PURE__ */ jsx5(SearchPreview, { presentation });
|
|
1322
|
+
if (presentation.detail === "web") return /* @__PURE__ */ jsxs4("section", { class: "scui-web-preview", children: [
|
|
1323
|
+
presentation.url ? /* @__PURE__ */ jsx5("code", { children: presentation.url }) : null,
|
|
1324
|
+
presentation.preview ? /* @__PURE__ */ jsx5("p", { children: stripAnsi(presentation.preview) }) : /* @__PURE__ */ jsx5("small", { children: pending ? "Waiting for the page" : "No page summary returned" })
|
|
1208
1325
|
] });
|
|
1209
|
-
if (presentation.detail === "agent") return /* @__PURE__ */
|
|
1210
|
-
|
|
1211
|
-
/* @__PURE__ */
|
|
1212
|
-
|
|
1326
|
+
if (presentation.detail === "agent") return /* @__PURE__ */ jsx5("section", { class: "scui-agent-preview", children: presentation.items?.length ? /* @__PURE__ */ jsx5("ol", { class: "scui-agent-roster", children: presentation.items.map((item, index) => /* @__PURE__ */ jsxs4("li", { children: [
|
|
1327
|
+
/* @__PURE__ */ jsx5("strong", { children: item.label }),
|
|
1328
|
+
/* @__PURE__ */ jsx5("small", { children: item.status })
|
|
1329
|
+
] }, `${item.label}:${index}`)) }) : presentation.preview ? /* @__PURE__ */ jsx5("pre", { children: stripAnsi(presentation.preview) }) : /* @__PURE__ */ jsx5("small", { children: pending ? "Agent is working" : "No textual handoff returned" }) });
|
|
1330
|
+
if (presentation.detail === "plan") return /* @__PURE__ */ jsx5("ol", { class: "scui-plan-preview", children: presentation.items?.map((item, index) => /* @__PURE__ */ jsxs4("li", { "data-status": item.status, children: [
|
|
1331
|
+
/* @__PURE__ */ jsx5("i", { "aria-hidden": "true" }),
|
|
1332
|
+
/* @__PURE__ */ jsx5("span", { children: item.label })
|
|
1213
1333
|
] }, `${item.label}:${index}`)) });
|
|
1214
|
-
return presentation.preview ? /* @__PURE__ */
|
|
1334
|
+
return presentation.preview ? /* @__PURE__ */ jsx5("pre", { class: "scui-tool-output", "data-error": failed, children: stripAnsi(presentation.preview) }) : null;
|
|
1215
1335
|
}
|
|
1216
1336
|
function ToolActions({ presentation, adapter }) {
|
|
1217
1337
|
const [copied, setCopied] = useState2(false);
|
|
@@ -1225,27 +1345,27 @@ function ToolActions({ presentation, adapter }) {
|
|
|
1225
1345
|
clearTimeout(reset.current);
|
|
1226
1346
|
reset.current = setTimeout(() => setCopied(false), 1500);
|
|
1227
1347
|
};
|
|
1228
|
-
return action ? /* @__PURE__ */
|
|
1348
|
+
return action ? /* @__PURE__ */ jsx5("div", { class: "scui-tool-actions", children: /* @__PURE__ */ jsx5("button", { type: "button", onClick: copy, children: copied ? "Copied" : action[0] }) }) : null;
|
|
1229
1349
|
}
|
|
1230
1350
|
function ToolStack({ tools }) {
|
|
1231
1351
|
if (tools.length < 2) return null;
|
|
1232
|
-
return /* @__PURE__ */
|
|
1352
|
+
return /* @__PURE__ */ jsx5("div", { class: "scui-tool-stack", "aria-label": "Coordinated tools", children: tools.map((tool) => /* @__PURE__ */ jsx5("span", { children: tool.replaceAll("__", " \xB7 ").replaceAll("_", " ") }, tool)) });
|
|
1233
1353
|
}
|
|
1234
1354
|
function TechnicalDetails({ entry }) {
|
|
1235
1355
|
if (!entry.arguments && !entry.resultText) return null;
|
|
1236
|
-
return /* @__PURE__ */
|
|
1237
|
-
/* @__PURE__ */
|
|
1238
|
-
/* @__PURE__ */
|
|
1239
|
-
entry.arguments ? /* @__PURE__ */
|
|
1240
|
-
/* @__PURE__ */
|
|
1241
|
-
/* @__PURE__ */
|
|
1242
|
-
/* @__PURE__ */
|
|
1243
|
-
/* @__PURE__ */
|
|
1356
|
+
return /* @__PURE__ */ jsxs4("details", { class: "scui-tool-technical", children: [
|
|
1357
|
+
/* @__PURE__ */ jsx5("summary", { children: "Technical details" }),
|
|
1358
|
+
/* @__PURE__ */ jsxs4("div", { children: [
|
|
1359
|
+
entry.arguments ? /* @__PURE__ */ jsxs4("section", { children: [
|
|
1360
|
+
/* @__PURE__ */ jsx5("strong", { children: "Native arguments" }),
|
|
1361
|
+
/* @__PURE__ */ jsx5("dl", { children: argumentRows(entry.arguments).map((row) => /* @__PURE__ */ jsxs4("div", { children: [
|
|
1362
|
+
/* @__PURE__ */ jsx5("dt", { children: row.label }),
|
|
1363
|
+
/* @__PURE__ */ jsx5("dd", { children: /* @__PURE__ */ jsx5("pre", { children: row.value }) })
|
|
1244
1364
|
] }, row.key)) })
|
|
1245
1365
|
] }) : null,
|
|
1246
|
-
entry.resultText ? /* @__PURE__ */
|
|
1247
|
-
/* @__PURE__ */
|
|
1248
|
-
/* @__PURE__ */
|
|
1366
|
+
entry.resultText ? /* @__PURE__ */ jsxs4("section", { children: [
|
|
1367
|
+
/* @__PURE__ */ jsx5("strong", { children: "Native result" }),
|
|
1368
|
+
/* @__PURE__ */ jsxs4("pre", { "data-error": entry.status === "error", children: [
|
|
1249
1369
|
entry.resultText,
|
|
1250
1370
|
entry.truncated ? "\n[truncated]" : ""
|
|
1251
1371
|
] })
|
|
@@ -1254,19 +1374,19 @@ function TechnicalDetails({ entry }) {
|
|
|
1254
1374
|
] });
|
|
1255
1375
|
}
|
|
1256
1376
|
function TranscriptEntry({ entry, state, adapter }) {
|
|
1257
|
-
if (entry.role === "request") return /* @__PURE__ */
|
|
1377
|
+
if (entry.role === "request") return /* @__PURE__ */ jsx5(RequestCard, { entry, adapter, canRespond: state.canRespond });
|
|
1258
1378
|
if (entry.role === "reasoning") {
|
|
1259
|
-
return /* @__PURE__ */
|
|
1260
|
-
/* @__PURE__ */
|
|
1261
|
-
/* @__PURE__ */
|
|
1379
|
+
return /* @__PURE__ */ jsxs4("details", { class: "scui-reasoning", open: entry.streaming, children: [
|
|
1380
|
+
/* @__PURE__ */ jsx5("summary", { children: entry.streaming ? "Reasoning\u2026" : "Reasoning" }),
|
|
1381
|
+
/* @__PURE__ */ jsx5(Markdown, { value: entry.text, copyText: adapter?.copyText })
|
|
1262
1382
|
] });
|
|
1263
1383
|
}
|
|
1264
|
-
if (entry.role === "notice" || entry.role === "system") return /* @__PURE__ */
|
|
1265
|
-
return /* @__PURE__ */
|
|
1266
|
-
/* @__PURE__ */
|
|
1267
|
-
/* @__PURE__ */
|
|
1268
|
-
entry.truncated ? /* @__PURE__ */
|
|
1269
|
-
/* @__PURE__ */
|
|
1384
|
+
if (entry.role === "notice" || entry.role === "system") return /* @__PURE__ */ jsx5("div", { class: "scui-notice", "data-code": entry.code, children: entry.text });
|
|
1385
|
+
return /* @__PURE__ */ jsxs4("article", { class: "scui-message", "data-role": entry.role, "aria-label": `${entry.role === "user" ? "Your" : "Assistant"} message`, children: [
|
|
1386
|
+
/* @__PURE__ */ jsx5(Markdown, { value: entry.text, copyText: adapter?.copyText }),
|
|
1387
|
+
/* @__PURE__ */ jsx5(ContextDisclosure, { context: entry.context }),
|
|
1388
|
+
entry.truncated ? /* @__PURE__ */ jsx5("small", { class: "scui-truncated", children: "Entry truncated by host \xB7 load native session for the complete value" }) : null,
|
|
1389
|
+
/* @__PURE__ */ jsx5(MessageMeta, { entry, adapter })
|
|
1270
1390
|
] });
|
|
1271
1391
|
}
|
|
1272
1392
|
function ToolRow({ entry, workspace, open = false, adapter }) {
|
|
@@ -1278,102 +1398,102 @@ function ToolRow({ entry, workspace, open = false, adapter }) {
|
|
|
1278
1398
|
const target = compactToolTarget(presentation.target, workspace);
|
|
1279
1399
|
const hasDetail = Boolean(entry.arguments || entry.resultText || presentation.preview || presentation.fields.length);
|
|
1280
1400
|
const category = presentation.category ?? toolCategory(entry);
|
|
1281
|
-
const summary = /* @__PURE__ */
|
|
1282
|
-
/* @__PURE__ */
|
|
1283
|
-
/* @__PURE__ */
|
|
1284
|
-
target ? /* @__PURE__ */
|
|
1285
|
-
/* @__PURE__ */
|
|
1286
|
-
entry.status === "pending" ? /* @__PURE__ */
|
|
1287
|
-
/* @__PURE__ */
|
|
1288
|
-
hasDetail ? /* @__PURE__ */
|
|
1401
|
+
const summary = /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
1402
|
+
/* @__PURE__ */ jsx5(ToolIcon, { category }),
|
|
1403
|
+
/* @__PURE__ */ jsx5("strong", { children: toolAction2(entry, category, presentation) }),
|
|
1404
|
+
target ? /* @__PURE__ */ jsx5("code", { class: "scui-tool-target", title: presentation.target, children: target }) : null,
|
|
1405
|
+
/* @__PURE__ */ jsx5("span", { class: "scui-spacer" }),
|
|
1406
|
+
entry.status === "pending" ? /* @__PURE__ */ jsx5(PendingElapsed, { now: adapter?.now }) : null,
|
|
1407
|
+
/* @__PURE__ */ jsx5("span", { class: "scui-tool-status", role: "status", "data-status": entry.status ?? "completed", "aria-label": entry.status ?? "completed", children: entry.status === "pending" ? /* @__PURE__ */ jsx5("i", {}) : /* @__PURE__ */ jsx5(UiIcon, { name: entry.status === "error" ? "close" : "check", size: 12 }) }),
|
|
1408
|
+
hasDetail ? /* @__PURE__ */ jsx5(UiIcon, { name: "chevron", size: 14, class: "scui-tool-chevron" }) : null
|
|
1289
1409
|
] });
|
|
1290
|
-
if (!hasDetail) return /* @__PURE__ */
|
|
1291
|
-
return /* @__PURE__ */
|
|
1292
|
-
/* @__PURE__ */
|
|
1293
|
-
/* @__PURE__ */
|
|
1294
|
-
/* @__PURE__ */
|
|
1295
|
-
/* @__PURE__ */
|
|
1296
|
-
/* @__PURE__ */
|
|
1297
|
-
presentation.fields.length ? /* @__PURE__ */
|
|
1298
|
-
/* @__PURE__ */
|
|
1299
|
-
/* @__PURE__ */
|
|
1410
|
+
if (!hasDetail) return /* @__PURE__ */ jsx5("div", { class: "scui-tool", "data-status": entry.status ?? "completed", "data-category": category, children: /* @__PURE__ */ jsx5("div", { class: "scui-tool-head", children: summary }) });
|
|
1411
|
+
return /* @__PURE__ */ jsxs4("details", { class: "scui-tool", "data-status": entry.status ?? "completed", "data-category": category, open: expanded, onToggle: (event) => setExpanded(event.currentTarget.open), children: [
|
|
1412
|
+
/* @__PURE__ */ jsx5("summary", { class: "scui-tool-head", children: summary }),
|
|
1413
|
+
/* @__PURE__ */ jsxs4("div", { class: "scui-tool-detail", children: [
|
|
1414
|
+
/* @__PURE__ */ jsx5(ToolMetrics, { presentation }),
|
|
1415
|
+
/* @__PURE__ */ jsx5(ToolStack, { tools: presentation.tools ?? [] }),
|
|
1416
|
+
/* @__PURE__ */ jsx5(ToolPreview, { presentation, entry }),
|
|
1417
|
+
presentation.fields.length ? /* @__PURE__ */ jsx5("dl", { class: "scui-tool-fields", children: presentation.fields.map((field) => /* @__PURE__ */ jsxs4("div", { children: [
|
|
1418
|
+
/* @__PURE__ */ jsx5("dt", { children: field.label }),
|
|
1419
|
+
/* @__PURE__ */ jsx5("dd", { children: field.value })
|
|
1300
1420
|
] }, field.label)) }) : null,
|
|
1301
|
-
/* @__PURE__ */
|
|
1302
|
-
/* @__PURE__ */
|
|
1421
|
+
/* @__PURE__ */ jsx5(ToolActions, { presentation, adapter }),
|
|
1422
|
+
/* @__PURE__ */ jsx5(TechnicalDetails, { entry })
|
|
1303
1423
|
] })
|
|
1304
1424
|
] });
|
|
1305
1425
|
}
|
|
1306
1426
|
function ActivityGroup({ entries, state, adapter }) {
|
|
1307
|
-
if (entries.length === 1) return /* @__PURE__ */
|
|
1427
|
+
if (entries.length === 1) return /* @__PURE__ */ jsx5("section", { class: "scui-activity", "data-single": "true", children: /* @__PURE__ */ jsx5(ToolRow, { entry: entries[0], workspace: state.workspace, adapter }) });
|
|
1308
1428
|
const active = entries.some((entry) => entry.status === "pending");
|
|
1309
1429
|
const [open, setOpen] = useState2(active);
|
|
1310
1430
|
const id = useId();
|
|
1311
1431
|
useEffect3(() => {
|
|
1312
1432
|
if (active) setOpen(true);
|
|
1313
1433
|
}, [active]);
|
|
1314
|
-
return /* @__PURE__ */
|
|
1315
|
-
/* @__PURE__ */
|
|
1316
|
-
/* @__PURE__ */
|
|
1317
|
-
/* @__PURE__ */
|
|
1318
|
-
/* @__PURE__ */
|
|
1319
|
-
/* @__PURE__ */
|
|
1434
|
+
return /* @__PURE__ */ jsxs4("section", { class: "scui-activity", children: [
|
|
1435
|
+
/* @__PURE__ */ jsxs4("button", { class: "scui-activity-head", type: "button", "aria-expanded": open, "aria-controls": id, onClick: () => setOpen((value) => !value), children: [
|
|
1436
|
+
/* @__PURE__ */ jsx5("span", { class: "scui-fold", "data-open": open, children: /* @__PURE__ */ jsx5(UiIcon, { name: "chevron", size: 14 }) }),
|
|
1437
|
+
/* @__PURE__ */ jsx5("strong", { children: activitySummary(entries) }),
|
|
1438
|
+
/* @__PURE__ */ jsx5("span", { class: "scui-spacer" }),
|
|
1439
|
+
/* @__PURE__ */ jsxs4("small", { children: [
|
|
1320
1440
|
entries.filter((entry) => entry.status !== "pending").length,
|
|
1321
1441
|
"/",
|
|
1322
1442
|
entries.length
|
|
1323
1443
|
] })
|
|
1324
1444
|
] }),
|
|
1325
|
-
open ? /* @__PURE__ */
|
|
1445
|
+
open ? /* @__PURE__ */ jsx5("div", { id, children: entries.map((entry) => /* @__PURE__ */ jsx5(ToolRow, { entry, workspace: state.workspace, adapter }, entry.id)) }) : null
|
|
1326
1446
|
] });
|
|
1327
1447
|
}
|
|
1328
1448
|
function TaskPlan({ plan }) {
|
|
1329
1449
|
if (!plan.items.length) return null;
|
|
1330
1450
|
const complete = plan.items.filter((item) => item.status === "completed" || item.status === "cancelled").length;
|
|
1331
|
-
return /* @__PURE__ */
|
|
1332
|
-
/* @__PURE__ */
|
|
1333
|
-
/* @__PURE__ */
|
|
1334
|
-
/* @__PURE__ */
|
|
1451
|
+
return /* @__PURE__ */ jsxs4("details", { class: "scui-plan", children: [
|
|
1452
|
+
/* @__PURE__ */ jsxs4("summary", { children: [
|
|
1453
|
+
/* @__PURE__ */ jsx5("span", { children: "Plan" }),
|
|
1454
|
+
/* @__PURE__ */ jsxs4("small", { children: [
|
|
1335
1455
|
complete,
|
|
1336
1456
|
"/",
|
|
1337
1457
|
plan.items.length
|
|
1338
1458
|
] })
|
|
1339
1459
|
] }),
|
|
1340
|
-
/* @__PURE__ */
|
|
1341
|
-
/* @__PURE__ */
|
|
1460
|
+
/* @__PURE__ */ jsx5("ol", { tabIndex: 0, "aria-label": "Task plan steps", children: plan.items.map((item) => /* @__PURE__ */ jsxs4("li", { "data-status": item.status, children: [
|
|
1461
|
+
/* @__PURE__ */ jsx5("i", { "aria-hidden": "true" }),
|
|
1342
1462
|
" ",
|
|
1343
|
-
/* @__PURE__ */
|
|
1463
|
+
/* @__PURE__ */ jsx5("span", { children: item.title })
|
|
1344
1464
|
] }, item.id)) })
|
|
1345
1465
|
] });
|
|
1346
1466
|
}
|
|
1347
1467
|
function SessionDetails({ semantics }) {
|
|
1348
1468
|
if (!semantics.fidelity && !semantics.residueCount && !semantics.parseErrors && !semantics.subagents.length) return null;
|
|
1349
|
-
return /* @__PURE__ */
|
|
1350
|
-
/* @__PURE__ */
|
|
1351
|
-
/* @__PURE__ */
|
|
1352
|
-
semantics.fidelity ? /* @__PURE__ */
|
|
1353
|
-
/* @__PURE__ */
|
|
1354
|
-
/* @__PURE__ */
|
|
1469
|
+
return /* @__PURE__ */ jsxs4("details", { class: "scui-details", children: [
|
|
1470
|
+
/* @__PURE__ */ jsx5("summary", { children: "Session details" }),
|
|
1471
|
+
/* @__PURE__ */ jsxs4("div", { children: [
|
|
1472
|
+
semantics.fidelity ? /* @__PURE__ */ jsxs4("p", { children: [
|
|
1473
|
+
/* @__PURE__ */ jsx5("strong", { children: "Fidelity" }),
|
|
1474
|
+
/* @__PURE__ */ jsx5("span", { children: semantics.fidelity.replaceAll("_", " ") })
|
|
1355
1475
|
] }) : null,
|
|
1356
|
-
/* @__PURE__ */
|
|
1357
|
-
/* @__PURE__ */
|
|
1358
|
-
/* @__PURE__ */
|
|
1476
|
+
/* @__PURE__ */ jsxs4("p", { children: [
|
|
1477
|
+
/* @__PURE__ */ jsx5("strong", { children: "Native records" }),
|
|
1478
|
+
/* @__PURE__ */ jsx5("span", { children: semantics.rawRecords })
|
|
1359
1479
|
] }),
|
|
1360
|
-
semantics.residueCount ? /* @__PURE__ */
|
|
1361
|
-
/* @__PURE__ */
|
|
1362
|
-
/* @__PURE__ */
|
|
1480
|
+
semantics.residueCount ? /* @__PURE__ */ jsxs4("p", { children: [
|
|
1481
|
+
/* @__PURE__ */ jsx5("strong", { children: "Residue" }),
|
|
1482
|
+
/* @__PURE__ */ jsxs4("span", { children: [
|
|
1363
1483
|
semantics.residueCount,
|
|
1364
1484
|
" retained"
|
|
1365
1485
|
] })
|
|
1366
1486
|
] }) : null,
|
|
1367
|
-
semantics.parseErrors ? /* @__PURE__ */
|
|
1368
|
-
/* @__PURE__ */
|
|
1369
|
-
/* @__PURE__ */
|
|
1487
|
+
semantics.parseErrors ? /* @__PURE__ */ jsxs4("p", { children: [
|
|
1488
|
+
/* @__PURE__ */ jsx5("strong", { children: "Parse diagnostics" }),
|
|
1489
|
+
/* @__PURE__ */ jsx5("span", { children: semantics.parseErrors })
|
|
1370
1490
|
] }) : null,
|
|
1371
|
-
semantics.subagents.map((agent) => /* @__PURE__ */
|
|
1372
|
-
/* @__PURE__ */
|
|
1491
|
+
semantics.subagents.map((agent) => /* @__PURE__ */ jsxs4("p", { children: [
|
|
1492
|
+
/* @__PURE__ */ jsxs4("strong", { children: [
|
|
1373
1493
|
agent.source,
|
|
1374
1494
|
" subagent"
|
|
1375
1495
|
] }),
|
|
1376
|
-
/* @__PURE__ */
|
|
1496
|
+
/* @__PURE__ */ jsxs4("span", { children: [
|
|
1377
1497
|
agent.messages,
|
|
1378
1498
|
" messages \xB7 ",
|
|
1379
1499
|
agent.fidelity.replaceAll("_", " ")
|
|
@@ -1392,7 +1512,7 @@ function ConversationAnnouncements({ state }) {
|
|
|
1392
1512
|
}
|
|
1393
1513
|
previousBusy.current = state.busy;
|
|
1394
1514
|
}, [state.busy, state.error, state.harness]);
|
|
1395
|
-
return /* @__PURE__ */
|
|
1515
|
+
return /* @__PURE__ */ jsx5("span", { class: "scui-sr-only", role: "status", "aria-live": "polite", "aria-atomic": "true", children: announcement });
|
|
1396
1516
|
}
|
|
1397
1517
|
function Conversation({ state, adapter, components = {}, slots = {}, memoryKey = state.attached?.key || `${state.harness}:${state.workspace}`, pending = null, unreadAfterMessages = null }) {
|
|
1398
1518
|
const scroller = useRef3(null);
|
|
@@ -1424,65 +1544,71 @@ function Conversation({ state, adapter, components = {}, slots = {}, memoryKey =
|
|
|
1424
1544
|
const element = scroller.current;
|
|
1425
1545
|
if (!element) return;
|
|
1426
1546
|
const anchor = earlierAnchor.current;
|
|
1427
|
-
if (anchor
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1547
|
+
if (anchor) {
|
|
1548
|
+
if (state.operation === "loadEarlier") anchor.seenOperation = true;
|
|
1549
|
+
const prepended = state.transcript.length > anchor.entries && state.transcript[0]?.id !== anchor.firstId;
|
|
1550
|
+
if (prepended) {
|
|
1551
|
+
element.scrollTop = anchor.top + (element.scrollHeight - anchor.height);
|
|
1552
|
+
earlierAnchor.current = null;
|
|
1553
|
+
remember({ top: element.scrollTop, atBottom: false });
|
|
1554
|
+
return;
|
|
1555
|
+
}
|
|
1556
|
+
if (state.error || anchor.seenOperation && state.operation !== "loadEarlier") earlierAnchor.current = null;
|
|
1432
1557
|
}
|
|
1433
1558
|
if (!restored.current) {
|
|
1434
1559
|
restored.current = true;
|
|
1435
1560
|
if (remembered.top !== null && !remembered.atBottom) element.scrollTop = remembered.top;
|
|
1436
1561
|
else pin();
|
|
1437
1562
|
} else if (atBottom) pin();
|
|
1438
|
-
}, [memoryKey, state.transcript, state.busy, state.operation, pendingMessage?.text, pendingMessage?.status]);
|
|
1439
|
-
return /* @__PURE__ */
|
|
1440
|
-
/* @__PURE__ */
|
|
1441
|
-
/* @__PURE__ */
|
|
1563
|
+
}, [memoryKey, state.transcript, state.busy, state.operation, state.error, pendingMessage?.text, pendingMessage?.status]);
|
|
1564
|
+
return /* @__PURE__ */ jsxs4("div", { class: "scui-conversation-wrap", children: [
|
|
1565
|
+
/* @__PURE__ */ jsx5(ConversationAnnouncements, { state }),
|
|
1566
|
+
/* @__PURE__ */ jsx5("div", { class: "scui-conversation", ref: scroller, tabIndex: 0, "aria-label": "Conversation", onScroll: (event) => {
|
|
1442
1567
|
const element = event.currentTarget;
|
|
1443
1568
|
const bottom = element.scrollHeight - element.scrollTop - element.clientHeight <= 64;
|
|
1444
1569
|
setAtBottom(bottom);
|
|
1445
1570
|
remember({ top: element.scrollTop, atBottom: bottom });
|
|
1446
|
-
}, children: /* @__PURE__ */
|
|
1447
|
-
Before ? /* @__PURE__ */
|
|
1448
|
-
/* @__PURE__ */
|
|
1449
|
-
/* @__PURE__ */
|
|
1450
|
-
state.history.hasEarlier ? /* @__PURE__ */
|
|
1571
|
+
}, children: /* @__PURE__ */ jsxs4("div", { children: [
|
|
1572
|
+
Before ? /* @__PURE__ */ jsx5(Before, { state, adapter, value: null }) : null,
|
|
1573
|
+
/* @__PURE__ */ jsx5(Plan, { plan: state.taskPlan, value: state.taskPlan, state, adapter }),
|
|
1574
|
+
/* @__PURE__ */ jsx5(SessionDetails, { semantics: state.semantics }),
|
|
1575
|
+
state.history.hasEarlier ? /* @__PURE__ */ jsx5("button", { class: "scui-load", type: "button", disabled: Boolean(state.operation), onClick: () => {
|
|
1451
1576
|
const element = scroller.current;
|
|
1452
|
-
if (element) earlierAnchor.current = { height: element.scrollHeight, top: element.scrollTop, entries: state.transcript.length };
|
|
1577
|
+
if (element) earlierAnchor.current = { height: element.scrollHeight, top: element.scrollTop, entries: state.transcript.length, firstId: state.transcript[0]?.id, seenOperation: false };
|
|
1453
1578
|
setAtBottom(false);
|
|
1454
1579
|
adapter.onIntent({ action: "loadEarlier" });
|
|
1455
1580
|
}, children: "Load earlier messages" }) : null,
|
|
1456
|
-
!blocks.length && state.startup !== "ready" ? /* @__PURE__ */
|
|
1457
|
-
!blocks.length && state.startup === "ready" ? Empty ? /* @__PURE__ */
|
|
1458
|
-
blocks.map((block, index) => /* @__PURE__ */
|
|
1459
|
-
index === unreadBlock ? /* @__PURE__ */
|
|
1460
|
-
block.kind === "activity" ? /* @__PURE__ */
|
|
1581
|
+
!blocks.length && state.startup !== "ready" ? /* @__PURE__ */ jsx5(LoadingStatus, { state }) : null,
|
|
1582
|
+
!blocks.length && state.startup === "ready" ? Empty ? /* @__PURE__ */ jsx5(Empty, { state, adapter, value: null }) : /* @__PURE__ */ jsx5("div", { class: "scui-empty", children: state.error ?? (state.harness ? `${harnessDisplayName(state.harness)} is listening. Say something.` : "No transcript yet.") }) : null,
|
|
1583
|
+
blocks.map((block, index) => /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
1584
|
+
index === unreadBlock ? /* @__PURE__ */ jsx5("div", { class: "scui-unread-divider", role: "separator", "aria-label": "New messages", children: /* @__PURE__ */ jsx5("span", { children: "New" }) }) : null,
|
|
1585
|
+
block.kind === "activity" ? /* @__PURE__ */ jsx5(Group, { value: block.entries, entries: block.entries, state, adapter }) : /* @__PURE__ */ jsx5(Entry, { value: block.entry, entry: block.entry, state, adapter })
|
|
1461
1586
|
] }, block.id)),
|
|
1462
|
-
pendingMessage ? /* @__PURE__ */
|
|
1463
|
-
/* @__PURE__ */
|
|
1464
|
-
/* @__PURE__ */
|
|
1465
|
-
|
|
1466
|
-
pendingMessage.status === "failed" ?
|
|
1467
|
-
|
|
1468
|
-
/* @__PURE__ */
|
|
1587
|
+
pendingMessage ? /* @__PURE__ */ jsxs4("article", { class: "scui-message scui-pending", "data-role": "user", "data-status": pendingMessage.status, "aria-label": "Your pending message", children: [
|
|
1588
|
+
/* @__PURE__ */ jsx5(Markdown, { value: pendingMessage.text, copyText: adapter?.copyText }),
|
|
1589
|
+
/* @__PURE__ */ jsx5(ContextDisclosure, { context: pendingMessage.context }),
|
|
1590
|
+
/* @__PURE__ */ jsxs4("footer", { children: [
|
|
1591
|
+
/* @__PURE__ */ jsx5("small", { children: pendingMessage.status === "failed" ? "Not sent" : "Sending\u2026" }),
|
|
1592
|
+
pendingMessage.status === "failed" ? /* @__PURE__ */ jsxs4("span", { children: [
|
|
1593
|
+
/* @__PURE__ */ jsx5("button", { type: "button", onClick: pendingMessage.onRetry, children: "Retry" }),
|
|
1594
|
+
/* @__PURE__ */ jsx5("button", { type: "button", onClick: pendingMessage.onEdit, children: "Edit" })
|
|
1469
1595
|
] }) : null
|
|
1470
1596
|
] })
|
|
1471
1597
|
] }) : null,
|
|
1472
|
-
state.busy ? /* @__PURE__ */
|
|
1473
|
-
/* @__PURE__ */
|
|
1474
|
-
/* @__PURE__ */
|
|
1475
|
-
/* @__PURE__ */
|
|
1476
|
-
/* @__PURE__ */
|
|
1477
|
-
/* @__PURE__ */
|
|
1598
|
+
state.busy ? /* @__PURE__ */ jsxs4("div", { class: "scui-working", role: "status", children: [
|
|
1599
|
+
/* @__PURE__ */ jsx5("span", { "aria-hidden": "true", children: "\u2726" }),
|
|
1600
|
+
/* @__PURE__ */ jsx5("i", {}),
|
|
1601
|
+
/* @__PURE__ */ jsx5("i", {}),
|
|
1602
|
+
/* @__PURE__ */ jsx5("i", {}),
|
|
1603
|
+
/* @__PURE__ */ jsxs4("small", { children: [
|
|
1478
1604
|
harnessDisplayName(state.harness),
|
|
1479
1605
|
" is working"
|
|
1480
1606
|
] })
|
|
1481
1607
|
] }) : null,
|
|
1482
|
-
After ? /* @__PURE__ */
|
|
1608
|
+
After ? /* @__PURE__ */ jsx5(After, { state, adapter, value: null }) : null
|
|
1483
1609
|
] }) }),
|
|
1484
|
-
!atBottom ? /* @__PURE__ */
|
|
1485
|
-
/* @__PURE__ */
|
|
1610
|
+
!atBottom ? /* @__PURE__ */ jsxs4("button", { class: "scui-latest", type: "button", onClick: pin, children: [
|
|
1611
|
+
/* @__PURE__ */ jsx5(UiIcon, { name: "down", size: 13 }),
|
|
1486
1612
|
" Latest"
|
|
1487
1613
|
] }) : null
|
|
1488
1614
|
] });
|
|
@@ -1490,7 +1616,7 @@ function Conversation({ state, adapter, components = {}, slots = {}, memoryKey =
|
|
|
1490
1616
|
|
|
1491
1617
|
// src/logo.jsx
|
|
1492
1618
|
import { useEffect as useEffect4 } from "preact/hooks";
|
|
1493
|
-
import { jsx as
|
|
1619
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "preact/jsx-runtime";
|
|
1494
1620
|
var LOGOS = {
|
|
1495
1621
|
"claude-code": {
|
|
1496
1622
|
viewBox: "-1 3.5 26 18",
|
|
@@ -1541,30 +1667,30 @@ function HarnessLogo({ id, activity, size = 28, onMissingLogo }) {
|
|
|
1541
1667
|
if (!logo) onMissingLogo?.(id);
|
|
1542
1668
|
}, [id, logo, onMissingLogo]);
|
|
1543
1669
|
if (!logo) return null;
|
|
1544
|
-
return /* @__PURE__ */
|
|
1545
|
-
/* @__PURE__ */
|
|
1546
|
-
activity && activity !== "idle" ? /* @__PURE__ */
|
|
1670
|
+
return /* @__PURE__ */ jsxs5("span", { class: "scui-logo", "data-harness": id, "data-activity": activity, style: `--scui-logo-size:${size}px`, "aria-hidden": "true", children: [
|
|
1671
|
+
/* @__PURE__ */ jsx6("svg", { viewBox: logo.viewBox, preserveAspectRatio: "xMidYMid meet", focusable: "false", children: logo.paths.map(([Tag, props], index) => /* @__PURE__ */ jsx6(Tag, { ...props }, index)) }),
|
|
1672
|
+
activity && activity !== "idle" ? /* @__PURE__ */ jsx6("i", {}) : null
|
|
1547
1673
|
] });
|
|
1548
1674
|
}
|
|
1549
1675
|
|
|
1550
1676
|
// src/sessions.jsx
|
|
1551
1677
|
import { useEffect as useEffect5, useLayoutEffect as useLayoutEffect3, useRef as useRef4, useState as useState3 } from "preact/hooks";
|
|
1552
|
-
import { jsx as
|
|
1678
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "preact/jsx-runtime";
|
|
1553
1679
|
var sessionListMemory = /* @__PURE__ */ new Map();
|
|
1554
1680
|
function SessionRow({ row, state, onOpen }) {
|
|
1555
1681
|
const activity = sessionActivity(state, row);
|
|
1556
1682
|
const attentionPreview = state.attention.find((item) => item.key === row.key)?.preview;
|
|
1557
1683
|
const title = sessionDisplayName(row);
|
|
1558
1684
|
const detail = attentionPreview || row.preview || (row.name && row.name !== title ? row.name : row.cwd);
|
|
1559
|
-
return /* @__PURE__ */
|
|
1560
|
-
/* @__PURE__ */
|
|
1561
|
-
/* @__PURE__ */
|
|
1562
|
-
/* @__PURE__ */
|
|
1563
|
-
/* @__PURE__ */
|
|
1564
|
-
/* @__PURE__ */
|
|
1685
|
+
return /* @__PURE__ */ jsxs6("button", { class: "scui-session", "data-active": row.active, "data-activity": activity, "data-session-key": row.key, type: "button", "aria-label": `${title} \xB7 ${harnessDisplayName(row.harness)}${detail ? ` \xB7 ${detail}` : ""}${row.age ? ` \xB7 ${row.age}` : ""}`, "aria-current": row.active ? "true" : void 0, onClick: () => onOpen(row), children: [
|
|
1686
|
+
/* @__PURE__ */ jsx7(HarnessLogo, { id: row.harness, activity, size: 34 }),
|
|
1687
|
+
/* @__PURE__ */ jsxs6("span", { class: "scui-session-copy", children: [
|
|
1688
|
+
/* @__PURE__ */ jsxs6("span", { children: [
|
|
1689
|
+
/* @__PURE__ */ jsx7("strong", { children: title }),
|
|
1690
|
+
/* @__PURE__ */ jsx7("small", { children: row.age })
|
|
1565
1691
|
] }),
|
|
1566
|
-
detail ? /* @__PURE__ */
|
|
1567
|
-
state.attachError?.key === row.key ? /* @__PURE__ */
|
|
1692
|
+
detail ? /* @__PURE__ */ jsx7("span", { children: /* @__PURE__ */ jsx7("small", { title: row.cwd, children: detail }) }) : null,
|
|
1693
|
+
state.attachError?.key === row.key ? /* @__PURE__ */ jsx7("em", { children: state.attachError.message }) : null
|
|
1568
1694
|
] })
|
|
1569
1695
|
] });
|
|
1570
1696
|
}
|
|
@@ -1595,48 +1721,48 @@ function SessionList({ state, adapter, onOpen, onNew, onClose, components = {},
|
|
|
1595
1721
|
Promise.resolve(result).then(() => setLoadingMore(false), () => setLoadingMore(false));
|
|
1596
1722
|
}
|
|
1597
1723
|
};
|
|
1598
|
-
return /* @__PURE__ */
|
|
1599
|
-
/* @__PURE__ */
|
|
1600
|
-
/* @__PURE__ */
|
|
1601
|
-
/* @__PURE__ */
|
|
1602
|
-
/* @__PURE__ */
|
|
1724
|
+
return /* @__PURE__ */ jsxs6("section", { class: "scui-list", ref: root, children: [
|
|
1725
|
+
/* @__PURE__ */ jsxs6("header", { class: "scui-head", children: [
|
|
1726
|
+
/* @__PURE__ */ jsxs6("span", { class: "scui-head-copy", children: [
|
|
1727
|
+
/* @__PURE__ */ jsx7("strong", { children: labels.chats }),
|
|
1728
|
+
/* @__PURE__ */ jsxs6("small", { children: [
|
|
1603
1729
|
state.sessions.length,
|
|
1604
1730
|
" recent conversations"
|
|
1605
1731
|
] })
|
|
1606
1732
|
] }),
|
|
1607
|
-
/* @__PURE__ */
|
|
1608
|
-
onClose ? /* @__PURE__ */
|
|
1733
|
+
/* @__PURE__ */ jsx7("button", { type: "button", "data-list-focus": "new", "aria-label": labels.newChat, disabled: !state.harnesses.some((item) => item.startable), onClick: onNew, children: /* @__PURE__ */ jsx7(UiIcon, { name: "plus", size: 18 }) }),
|
|
1734
|
+
onClose ? /* @__PURE__ */ jsx7("button", { type: "button", "aria-label": "Close", onClick: onClose, children: /* @__PURE__ */ jsx7(UiIcon, { name: "close", size: 18 }) }) : null
|
|
1609
1735
|
] }),
|
|
1610
|
-
state.startup !== "ready" ? /* @__PURE__ */
|
|
1611
|
-
state.sessions.length > 4 ? /* @__PURE__ */
|
|
1612
|
-
/* @__PURE__ */
|
|
1613
|
-
/* @__PURE__ */
|
|
1736
|
+
state.startup !== "ready" ? /* @__PURE__ */ jsx7(LoadingStatus, { state, compact: rows.length > 0 }) : null,
|
|
1737
|
+
state.sessions.length > 4 ? /* @__PURE__ */ jsxs6("label", { class: "scui-search", children: [
|
|
1738
|
+
/* @__PURE__ */ jsx7(UiIcon, { name: "search", size: 15 }),
|
|
1739
|
+
/* @__PURE__ */ jsx7("input", { type: "search", "aria-label": labels.searchChats, placeholder: labels.searchChats, value: query, onInput: (event) => {
|
|
1614
1740
|
const value = event.currentTarget.value;
|
|
1615
1741
|
setQuery(value);
|
|
1616
1742
|
boundedSet(sessionListMemory, memoryKey, { query: value, top: 0 });
|
|
1617
1743
|
if (rowScroller.current) rowScroller.current.scrollTop = 0;
|
|
1618
1744
|
} }),
|
|
1619
|
-
/* @__PURE__ */
|
|
1745
|
+
/* @__PURE__ */ jsx7("small", { children: rows.length })
|
|
1620
1746
|
] }) : null,
|
|
1621
|
-
/* @__PURE__ */
|
|
1622
|
-
!rows.length && state.startup === "ready" ? /* @__PURE__ */
|
|
1623
|
-
rows.map((row) => /* @__PURE__ */
|
|
1624
|
-
state.history.hasMoreSessions ? /* @__PURE__ */
|
|
1747
|
+
/* @__PURE__ */ jsxs6("div", { class: "scui-session-rows", ref: rowScroller, onScroll: (event) => boundedSet(sessionListMemory, memoryKey, { query, top: event.currentTarget.scrollTop }), children: [
|
|
1748
|
+
!rows.length && state.startup === "ready" ? /* @__PURE__ */ jsx7("div", { class: "scui-empty", children: query ? "No chats match your search." : state.error ?? "No coding chats found." }) : null,
|
|
1749
|
+
rows.map((row) => /* @__PURE__ */ jsx7(Row, { value: row, row, state, adapter, onOpen }, row.key)),
|
|
1750
|
+
state.history.hasMoreSessions ? /* @__PURE__ */ jsx7("button", { class: "scui-load", type: "button", disabled: loadingMore, onClick: loadMore, children: loadingMore ? "Loading older chats\u2026" : "Load older chats" }) : null
|
|
1625
1751
|
] })
|
|
1626
1752
|
] });
|
|
1627
1753
|
}
|
|
1628
1754
|
|
|
1629
1755
|
// src/messenger.jsx
|
|
1630
|
-
import { jsx as
|
|
1756
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "preact/jsx-runtime";
|
|
1631
1757
|
var pendingMessageMemory = /* @__PURE__ */ new Map();
|
|
1632
1758
|
var messengerViewMemory = /* @__PURE__ */ new Map();
|
|
1633
1759
|
var newChatMemory = /* @__PURE__ */ new Map();
|
|
1634
1760
|
var TRACKED_ACTIONS = /* @__PURE__ */ new Set(["resume", "join", "detach", "branch", "reduce", "terminal", "export", "interrupt", "respond", "refresh", "loadEarlier", "loadSessions"]);
|
|
1635
1761
|
function Receipt({ state, adapter }) {
|
|
1636
1762
|
const receipt = state.reductionReceipt;
|
|
1637
|
-
if (receipt) return /* @__PURE__ */
|
|
1638
|
-
/* @__PURE__ */
|
|
1639
|
-
/* @__PURE__ */
|
|
1763
|
+
if (receipt) return /* @__PURE__ */ jsx8("div", { class: "scui-receipt", children: /* @__PURE__ */ jsxs7("span", { children: [
|
|
1764
|
+
/* @__PURE__ */ jsx8("strong", { children: "Reduced and verified" }),
|
|
1765
|
+
/* @__PURE__ */ jsxs7("small", { children: [
|
|
1640
1766
|
receipt.sourceTokens.toLocaleString(),
|
|
1641
1767
|
" \u2192 ",
|
|
1642
1768
|
receipt.reducedTokens.toLocaleString(),
|
|
@@ -1645,27 +1771,27 @@ function Receipt({ state, adapter }) {
|
|
|
1645
1771
|
"\xD7 \xB7 reversible"
|
|
1646
1772
|
] })
|
|
1647
1773
|
] }) });
|
|
1648
|
-
if (state.exportReceipt) return /* @__PURE__ */
|
|
1649
|
-
/* @__PURE__ */
|
|
1650
|
-
/* @__PURE__ */
|
|
1774
|
+
if (state.exportReceipt) return /* @__PURE__ */ jsxs7("div", { class: "scui-receipt", children: [
|
|
1775
|
+
/* @__PURE__ */ jsxs7("span", { children: [
|
|
1776
|
+
/* @__PURE__ */ jsxs7("strong", { children: [
|
|
1651
1777
|
"Lossless export ready \xB7 ",
|
|
1652
1778
|
harnessDisplayName(state.exportReceipt.targetHarness)
|
|
1653
1779
|
] }),
|
|
1654
|
-
/* @__PURE__ */
|
|
1780
|
+
/* @__PURE__ */ jsxs7("small", { children: [
|
|
1655
1781
|
state.exportReceipt.path,
|
|
1656
1782
|
" \xB7 ",
|
|
1657
1783
|
state.exportReceipt.files,
|
|
1658
1784
|
" files"
|
|
1659
1785
|
] })
|
|
1660
1786
|
] }),
|
|
1661
|
-
/* @__PURE__ */
|
|
1787
|
+
/* @__PURE__ */ jsx8("button", { type: "button", onClick: () => adapter.copyText?.(state.exportReceipt.path), children: "Copy path" })
|
|
1662
1788
|
] });
|
|
1663
|
-
if (state.terminalHandoff) return /* @__PURE__ */
|
|
1664
|
-
/* @__PURE__ */
|
|
1665
|
-
/* @__PURE__ */
|
|
1666
|
-
/* @__PURE__ */
|
|
1789
|
+
if (state.terminalHandoff) return /* @__PURE__ */ jsxs7("div", { class: "scui-receipt", children: [
|
|
1790
|
+
/* @__PURE__ */ jsxs7("span", { children: [
|
|
1791
|
+
/* @__PURE__ */ jsx8("strong", { children: "Terminal handoff ready" }),
|
|
1792
|
+
/* @__PURE__ */ jsx8("small", { children: state.terminalHandoff.cwd })
|
|
1667
1793
|
] }),
|
|
1668
|
-
/* @__PURE__ */
|
|
1794
|
+
/* @__PURE__ */ jsx8("button", { type: "button", onClick: () => adapter.copyText?.(terminalCommand(state.terminalHandoff)), children: "Copy command" })
|
|
1669
1795
|
] });
|
|
1670
1796
|
return null;
|
|
1671
1797
|
}
|
|
@@ -1733,13 +1859,13 @@ function ConversationActions({ state, adapter, actionPending }) {
|
|
|
1733
1859
|
const index = event.key === "Home" ? 0 : event.key === "End" ? items.length - 1 : event.key === "ArrowDown" ? (current + 1) % items.length : (current <= 0 ? items.length : current) - 1;
|
|
1734
1860
|
items[index].focus({ preventScroll: true });
|
|
1735
1861
|
};
|
|
1736
|
-
return /* @__PURE__ */
|
|
1862
|
+
return /* @__PURE__ */ jsxs7("div", { class: "scui-menu", ref: root, onBlur: (event) => {
|
|
1737
1863
|
if (event.relatedTarget && !event.currentTarget.contains(event.relatedTarget)) setOpen(false);
|
|
1738
1864
|
}, children: [
|
|
1739
|
-
/* @__PURE__ */
|
|
1740
|
-
open ? /* @__PURE__ */
|
|
1741
|
-
/* @__PURE__ */
|
|
1742
|
-
group.items.map((item) => /* @__PURE__ */
|
|
1865
|
+
/* @__PURE__ */ jsx8("button", { ref: trigger, class: "scui-menu-trigger", type: "button", "aria-label": "Conversation actions", "aria-haspopup": "menu", "aria-expanded": open, "aria-controls": open ? menuId : void 0, onClick: () => setOpen((value) => !value), children: /* @__PURE__ */ jsx8(UiIcon, { name: "menu", size: 18 }) }),
|
|
1866
|
+
open ? /* @__PURE__ */ jsx8("div", { ref: panel, id: menuId, class: "scui-menu-panel", role: "menu", "aria-label": "Conversation actions", onKeyDown: navigate, children: groups.map((group) => /* @__PURE__ */ jsxs7("section", { role: "group", "aria-label": group.label, children: [
|
|
1867
|
+
/* @__PURE__ */ jsx8("strong", { children: group.label }),
|
|
1868
|
+
group.items.map((item) => /* @__PURE__ */ jsx8("button", { role: "menuitem", type: "button", disabled: actionPending, onClick: () => dispatch(item.intent), children: item.label }, item.key))
|
|
1743
1869
|
] }, group.label)) }) : null
|
|
1744
1870
|
] });
|
|
1745
1871
|
}
|
|
@@ -1752,20 +1878,20 @@ function ChatHeader({ state, adapter, pendingStatus, actionPending, onBack, onNe
|
|
|
1752
1878
|
useEffect6(() => {
|
|
1753
1879
|
if (state.mode === "mirror" && !state.canSend) back.current?.focus({ preventScroll: true });
|
|
1754
1880
|
}, []);
|
|
1755
|
-
return /* @__PURE__ */
|
|
1756
|
-
/* @__PURE__ */
|
|
1757
|
-
/* @__PURE__ */
|
|
1758
|
-
/* @__PURE__ */
|
|
1759
|
-
/* @__PURE__ */
|
|
1760
|
-
/* @__PURE__ */
|
|
1881
|
+
return /* @__PURE__ */ jsxs7("header", { class: "scui-head scui-chat-head", children: [
|
|
1882
|
+
/* @__PURE__ */ jsx8("button", { ref: back, type: "button", "aria-label": "Back to chats", onClick: onBack, children: /* @__PURE__ */ jsx8(UiIcon, { name: "back", size: 18 }) }),
|
|
1883
|
+
/* @__PURE__ */ jsx8(HarnessLogo, { id: harness, size: 28 }),
|
|
1884
|
+
/* @__PURE__ */ jsxs7("span", { class: "scui-head-copy", children: [
|
|
1885
|
+
/* @__PURE__ */ jsx8("strong", { children: title }),
|
|
1886
|
+
/* @__PURE__ */ jsxs7("small", { children: [
|
|
1761
1887
|
harnessDisplayName(harness),
|
|
1762
1888
|
" \xB7 ",
|
|
1763
1889
|
status
|
|
1764
1890
|
] })
|
|
1765
1891
|
] }),
|
|
1766
|
-
menu ? /* @__PURE__ */
|
|
1767
|
-
/* @__PURE__ */
|
|
1768
|
-
onClose ? /* @__PURE__ */
|
|
1892
|
+
menu ? /* @__PURE__ */ jsx8(ConversationActions, { state, adapter, actionPending }) : null,
|
|
1893
|
+
/* @__PURE__ */ jsx8("button", { type: "button", "aria-label": "New chat", onClick: onNew, children: /* @__PURE__ */ jsx8(UiIcon, { name: "plus", size: 18 }) }),
|
|
1894
|
+
onClose ? /* @__PURE__ */ jsx8("button", { type: "button", "aria-label": "Close", onClick: onClose, children: /* @__PURE__ */ jsx8(UiIcon, { name: "close", size: 18 }) }) : null
|
|
1769
1895
|
] });
|
|
1770
1896
|
}
|
|
1771
1897
|
function Chat({ state, adapter, onBack, onNew, onClose, components, slots, labels }) {
|
|
@@ -1797,8 +1923,9 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
1797
1923
|
if (pending.status === "sending" && state.busy && !pending.seenBusy) setPending({ ...pending, seenBusy: true });
|
|
1798
1924
|
else if (pending.status === "sending" && state.error && !state.busy && !state.operation && (pending.seenBusy || state.error !== pending.initialError)) setPending({ ...pending, status: "failed" });
|
|
1799
1925
|
}, [pending, state.busy, state.error, state.operation, state.transcript]);
|
|
1800
|
-
const beginPending = (text) => setPending({
|
|
1926
|
+
const beginPending = (text, context = []) => setPending({
|
|
1801
1927
|
text,
|
|
1928
|
+
context,
|
|
1802
1929
|
status: "sending",
|
|
1803
1930
|
initialError: state.error,
|
|
1804
1931
|
seenBusy: state.busy,
|
|
@@ -1806,13 +1933,13 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
1806
1933
|
});
|
|
1807
1934
|
const retryPending = () => {
|
|
1808
1935
|
if (!pending) return;
|
|
1809
|
-
adapter.onIntent({ action: "send", text: pending.text });
|
|
1936
|
+
adapter.onIntent({ action: "send", text: pending.text, ...pending.context?.length ? { context: pending.context } : {} });
|
|
1810
1937
|
setPending({ ...pending, status: "sending", initialError: state.error, seenBusy: state.busy });
|
|
1811
1938
|
};
|
|
1812
1939
|
const editPending = () => {
|
|
1813
1940
|
if (!pending) return;
|
|
1814
1941
|
restoreSequence.current += 1;
|
|
1815
|
-
setRestoreDraft({ id: restoreSequence.current, text: pending.text });
|
|
1942
|
+
setRestoreDraft({ id: restoreSequence.current, text: pending.text, context: pending.context });
|
|
1816
1943
|
setPending({ ...pending, status: "editing" });
|
|
1817
1944
|
};
|
|
1818
1945
|
useEffect6(() => {
|
|
@@ -1858,34 +1985,37 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
1858
1985
|
setPendingAction(null);
|
|
1859
1986
|
}
|
|
1860
1987
|
}, [pendingAction, state.error, state.operation]);
|
|
1861
|
-
const pendingMessage = pending && pending.status !== "editing" ? { text: pending.text, status: pending.status, onRetry: retryPending, onEdit: editPending } : null;
|
|
1988
|
+
const pendingMessage = pending && pending.status !== "editing" ? { text: pending.text, context: pending.context, status: pending.status, onRetry: retryPending, onEdit: editPending } : null;
|
|
1862
1989
|
const action = state.operation || pendingAction?.action || null;
|
|
1863
1990
|
const actionLabel = operationLabel(action);
|
|
1864
1991
|
const actionState = action ? { ...state, operation: action, canInterrupt: false, canRespond: false } : state;
|
|
1865
1992
|
const unreadAfterMessages = state.attention.find((item) => item.key === state.attached?.key)?.afterMessages ?? null;
|
|
1866
|
-
return /* @__PURE__ */
|
|
1867
|
-
Header ? /* @__PURE__ */
|
|
1868
|
-
actionLabel ? /* @__PURE__ */
|
|
1869
|
-
/* @__PURE__ */
|
|
1993
|
+
return /* @__PURE__ */ jsxs7("section", { class: "scui-chat", children: [
|
|
1994
|
+
Header ? /* @__PURE__ */ jsx8(Header, { state: actionState, adapter: trackedAdapter, value: null }) : /* @__PURE__ */ jsx8(ChatHeader, { state: actionState, adapter: trackedAdapter, pendingStatus: pending?.status ?? null, actionPending: Boolean(action), onBack, onNew, onClose }),
|
|
1995
|
+
actionLabel ? /* @__PURE__ */ jsxs7("div", { class: "scui-operation", role: "status", children: [
|
|
1996
|
+
/* @__PURE__ */ jsx8("i", {}),
|
|
1870
1997
|
actionLabel
|
|
1871
1998
|
] }) : null,
|
|
1872
|
-
state.error ? /* @__PURE__ */
|
|
1873
|
-
/* @__PURE__ */
|
|
1874
|
-
state.recoverable ? /* @__PURE__ */
|
|
1999
|
+
state.error ? /* @__PURE__ */ jsxs7("div", { class: "scui-error", role: "alert", children: [
|
|
2000
|
+
/* @__PURE__ */ jsx8("span", { children: state.error }),
|
|
2001
|
+
state.recoverable ? /* @__PURE__ */ jsx8("button", { type: "button", disabled: Boolean(action), onClick: () => trackedAdapter.onIntent({ action: "refresh" }), children: "Retry" }) : null
|
|
1875
2002
|
] }) : null,
|
|
1876
|
-
/* @__PURE__ */
|
|
1877
|
-
/* @__PURE__ */
|
|
1878
|
-
/* @__PURE__ */
|
|
1879
|
-
state.mode !== "mirror" || state.canSend ? /* @__PURE__ */
|
|
2003
|
+
/* @__PURE__ */ jsx8(Receipt, { state, adapter }),
|
|
2004
|
+
/* @__PURE__ */ jsx8(Conversation, { state: actionState, adapter: trackedAdapter, components, slots, memoryKey, pending: pendingMessage, unreadAfterMessages }, memoryKey),
|
|
2005
|
+
/* @__PURE__ */ jsx8(ContinuationBar, { state: actionState, adapter: trackedAdapter, labels }),
|
|
2006
|
+
state.mode !== "mirror" || state.canSend ? /* @__PURE__ */ jsx8(Composer, { state: actionState, adapter: trackedAdapter, labels, memoryKey, pendingStatus: pending?.status ?? null, restoreDraft, onDraftRestored: (id) => setRestoreDraft((value) => value?.id === id ? null : value), onPending: beginPending }, memoryKey) : null
|
|
1880
2007
|
] });
|
|
1881
2008
|
}
|
|
1882
2009
|
function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey }) {
|
|
1883
2010
|
const startable = state.harnesses.filter((item) => item.startable);
|
|
1884
2011
|
const startableKey = startable.map((item) => item.id).join("\0");
|
|
1885
|
-
const remembered = newChatMemory.get(memoryKey) ?? { harness: startable[0]?.id ?? "", draft: "" };
|
|
2012
|
+
const remembered = newChatMemory.get(memoryKey) ?? { harness: startable[0]?.id ?? "", draft: "", context: [] };
|
|
1886
2013
|
const [harness, setHarness] = useState4(remembered.harness);
|
|
1887
2014
|
const [draft, setDraft] = useState4(remembered.draft);
|
|
2015
|
+
const [context, setContext] = useState4(remembered.context);
|
|
1888
2016
|
const [starting, setStarting] = useState4(null);
|
|
2017
|
+
const [picking, setPicking] = useState4(false);
|
|
2018
|
+
const [pickerError, setPickerError] = useState4(null);
|
|
1889
2019
|
const startSequence = useRef5(0);
|
|
1890
2020
|
const textarea = useRef5(null);
|
|
1891
2021
|
useAutosizeTextarea(textarea, draft);
|
|
@@ -1893,7 +2023,7 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
|
|
|
1893
2023
|
if (startable.some((item) => item.id === harness)) return;
|
|
1894
2024
|
const next = startable[0]?.id ?? "";
|
|
1895
2025
|
setHarness(next);
|
|
1896
|
-
boundedSet(newChatMemory, memoryKey, { harness: next, draft });
|
|
2026
|
+
boundedSet(newChatMemory, memoryKey, { harness: next, draft, context });
|
|
1897
2027
|
}, [harness, startableKey]);
|
|
1898
2028
|
useEffect6(() => {
|
|
1899
2029
|
if (!starting) return;
|
|
@@ -1909,60 +2039,79 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
|
|
|
1909
2039
|
useEffect6(() => {
|
|
1910
2040
|
textarea.current?.focus({ preventScroll: true });
|
|
1911
2041
|
}, []);
|
|
2042
|
+
const pickContext = () => {
|
|
2043
|
+
if (!adapter.pickContext || picking || context.length >= MAX_CONTEXT_ITEMS) return;
|
|
2044
|
+
setPicking(true);
|
|
2045
|
+
setPickerError(null);
|
|
2046
|
+
Promise.resolve().then(() => adapter.pickContext()).then((picked) => {
|
|
2047
|
+
setContext((current) => {
|
|
2048
|
+
const next = mergeContext(current, picked);
|
|
2049
|
+
boundedSet(newChatMemory, memoryKey, { harness, draft, context: next });
|
|
2050
|
+
return next;
|
|
2051
|
+
});
|
|
2052
|
+
}, (error) => setPickerError(error instanceof Error ? error.message : "Could not attach context.")).finally(() => setPicking(false));
|
|
2053
|
+
};
|
|
1912
2054
|
const send = () => {
|
|
1913
2055
|
const text = draft.trim();
|
|
1914
2056
|
if (!text || !harness || starting) return;
|
|
1915
2057
|
const id = startSequence.current + 1;
|
|
1916
2058
|
startSequence.current = id;
|
|
1917
2059
|
setStarting({ id, attachedKey: state.attached?.key ?? null, busy: state.busy, initialError: state.error });
|
|
1918
|
-
const result = adapter.onIntent({ action: "new", harness, text });
|
|
2060
|
+
const result = adapter.onIntent({ action: "new", harness, text, ...context.length ? { context } : {} });
|
|
1919
2061
|
if (result && typeof result.then === "function") {
|
|
1920
2062
|
Promise.resolve(result).catch(() => setStarting((current) => current?.id === id ? null : current));
|
|
1921
2063
|
}
|
|
1922
2064
|
};
|
|
1923
|
-
return /* @__PURE__ */
|
|
1924
|
-
/* @__PURE__ */
|
|
1925
|
-
/* @__PURE__ */
|
|
1926
|
-
/* @__PURE__ */
|
|
1927
|
-
/* @__PURE__ */
|
|
1928
|
-
/* @__PURE__ */
|
|
2065
|
+
return /* @__PURE__ */ jsxs7("section", { class: "scui-chat", children: [
|
|
2066
|
+
/* @__PURE__ */ jsxs7("header", { class: "scui-head", children: [
|
|
2067
|
+
/* @__PURE__ */ jsx8("button", { type: "button", "aria-label": "Back", onClick: onBack, children: /* @__PURE__ */ jsx8(UiIcon, { name: "back", size: 18 }) }),
|
|
2068
|
+
/* @__PURE__ */ jsxs7("span", { class: "scui-head-copy", children: [
|
|
2069
|
+
/* @__PURE__ */ jsx8("strong", { children: labels.newChat }),
|
|
2070
|
+
/* @__PURE__ */ jsx8("small", { children: "No session is created until you send" })
|
|
1929
2071
|
] }),
|
|
1930
|
-
onClose ? /* @__PURE__ */
|
|
2072
|
+
onClose ? /* @__PURE__ */ jsx8("button", { type: "button", "aria-label": "Close", onClick: onClose, children: /* @__PURE__ */ jsx8(UiIcon, { name: "close", size: 18 }) }) : null
|
|
1931
2073
|
] }),
|
|
1932
|
-
starting ? /* @__PURE__ */
|
|
1933
|
-
/* @__PURE__ */
|
|
2074
|
+
starting ? /* @__PURE__ */ jsxs7("div", { class: "scui-operation", role: "status", children: [
|
|
2075
|
+
/* @__PURE__ */ jsx8("i", {}),
|
|
1934
2076
|
operationLabel("start")
|
|
1935
2077
|
] }) : null,
|
|
1936
|
-
/* @__PURE__ */
|
|
1937
|
-
/* @__PURE__ */
|
|
1938
|
-
/* @__PURE__ */
|
|
1939
|
-
/* @__PURE__ */
|
|
2078
|
+
/* @__PURE__ */ jsxs7("div", { class: "scui-new", children: [
|
|
2079
|
+
/* @__PURE__ */ jsx8("span", { "aria-hidden": "true", children: "\u2726" }),
|
|
2080
|
+
/* @__PURE__ */ jsx8("strong", { children: "What should the agent build or fix?" }),
|
|
2081
|
+
/* @__PURE__ */ jsx8("small", { children: "Choose a coding harness and send the first message." })
|
|
1940
2082
|
] }),
|
|
1941
|
-
/* @__PURE__ */
|
|
1942
|
-
/* @__PURE__ */
|
|
1943
|
-
/* @__PURE__ */
|
|
1944
|
-
/* @__PURE__ */
|
|
1945
|
-
/* @__PURE__ */
|
|
2083
|
+
/* @__PURE__ */ jsxs7("div", { class: "scui-compose", children: [
|
|
2084
|
+
/* @__PURE__ */ jsxs7("label", { class: "scui-harness-picker", children: [
|
|
2085
|
+
/* @__PURE__ */ jsx8(HarnessLogo, { id: harness, size: 24 }),
|
|
2086
|
+
/* @__PURE__ */ jsx8("span", { children: "Coding harness" }),
|
|
2087
|
+
/* @__PURE__ */ jsx8("select", { value: harness, disabled: Boolean(starting), onChange: (event) => {
|
|
1946
2088
|
const value = event.currentTarget.value;
|
|
1947
2089
|
setHarness(value);
|
|
1948
|
-
boundedSet(newChatMemory, memoryKey, { harness: value, draft });
|
|
1949
|
-
}, children: state.harnesses.map((item) => /* @__PURE__ */
|
|
2090
|
+
boundedSet(newChatMemory, memoryKey, { harness: value, draft, context });
|
|
2091
|
+
}, children: state.harnesses.map((item) => /* @__PURE__ */ jsxs7("option", { value: item.id, disabled: !item.startable, children: [
|
|
1950
2092
|
item.label,
|
|
1951
2093
|
item.startable ? "" : " \xB7 unavailable"
|
|
1952
2094
|
] }, item.id)) })
|
|
1953
2095
|
] }),
|
|
1954
|
-
/* @__PURE__ */
|
|
1955
|
-
|
|
2096
|
+
/* @__PURE__ */ jsx8(ContextTray, { items: context, onRemove: (index) => setContext((items) => {
|
|
2097
|
+
const next = items.filter((_, itemIndex) => itemIndex !== index);
|
|
2098
|
+
boundedSet(newChatMemory, memoryKey, { harness, draft, context: next });
|
|
2099
|
+
return next;
|
|
2100
|
+
}) }),
|
|
2101
|
+
pickerError ? /* @__PURE__ */ jsx8("small", { class: "scui-context-error", role: "alert", children: pickerError }) : null,
|
|
2102
|
+
/* @__PURE__ */ jsxs7("div", { class: "scui-envelope", children: [
|
|
2103
|
+
adapter.pickContext ? /* @__PURE__ */ jsx8("button", { class: "scui-attach", type: "button", "aria-label": "Attach context", disabled: picking || context.length >= MAX_CONTEXT_ITEMS || Boolean(starting), onClick: pickContext, children: picking ? /* @__PURE__ */ jsx8("i", { class: "scui-control-spinner" }) : /* @__PURE__ */ jsx8(UiIcon, { name: "attach", size: 17 }) }) : null,
|
|
2104
|
+
/* @__PURE__ */ jsx8("textarea", { ref: textarea, rows: 3, "aria-label": "Message coding agent", placeholder: startable.length ? "What should the agent do?" : "No coding harness is available", value: draft, disabled: !startable.length || Boolean(starting), onInput: (event) => {
|
|
1956
2105
|
const value = event.currentTarget.value;
|
|
1957
2106
|
setDraft(value);
|
|
1958
|
-
boundedSet(newChatMemory, memoryKey, { harness, draft: value });
|
|
2107
|
+
boundedSet(newChatMemory, memoryKey, { harness, draft: value, context });
|
|
1959
2108
|
}, onKeyDown: (event) => {
|
|
1960
2109
|
if (isSendKey(event)) {
|
|
1961
2110
|
event.preventDefault();
|
|
1962
2111
|
send();
|
|
1963
2112
|
}
|
|
1964
2113
|
} }),
|
|
1965
|
-
/* @__PURE__ */
|
|
2114
|
+
/* @__PURE__ */ jsx8("span", { children: /* @__PURE__ */ jsx8("button", { type: "button", class: "scui-send", "aria-label": "Start chat", disabled: !draft.trim() || !harness || Boolean(starting), onClick: send, children: starting ? /* @__PURE__ */ jsx8("i", { class: "scui-control-spinner" }) : /* @__PURE__ */ jsx8(UiIcon, { name: "send", size: 17 }) }) })
|
|
1966
2115
|
] })
|
|
1967
2116
|
] })
|
|
1968
2117
|
] });
|
|
@@ -1994,40 +2143,40 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
1994
2143
|
};
|
|
1995
2144
|
const close = () => adapter.onClose?.();
|
|
1996
2145
|
const Footer = slots.footer;
|
|
1997
|
-
return /* @__PURE__ */
|
|
1998
|
-
view === "list" ? /* @__PURE__ */
|
|
2146
|
+
return /* @__PURE__ */ jsxs7("main", { class: `scui-root ${className}`, "data-view": view, "data-mode": state.mode, "aria-label": "Supercode messenger", children: [
|
|
2147
|
+
view === "list" ? /* @__PURE__ */ jsx8(SessionList, { state, adapter, focusKey: listFocus, onOpen: open, onNew: () => {
|
|
1999
2148
|
setListFocus("@new");
|
|
2000
2149
|
setView("new");
|
|
2001
2150
|
}, onClose: adapter.onClose ? close : void 0, components, labels: copy, memoryKey }) : null,
|
|
2002
|
-
view === "new" ? /* @__PURE__ */
|
|
2003
|
-
view === "chat" ? /* @__PURE__ */
|
|
2151
|
+
view === "new" ? /* @__PURE__ */ jsx8(NewChat, { state, adapter, onBack: () => setView("list"), onClose: adapter.onClose ? close : void 0, onStarted: () => setView("chat"), labels: copy, memoryKey }) : null,
|
|
2152
|
+
view === "chat" ? /* @__PURE__ */ jsx8(Chat, { state, adapter, onBack: () => {
|
|
2004
2153
|
setListFocus(state.attached?.key ?? listFocus);
|
|
2005
2154
|
setView("list");
|
|
2006
2155
|
}, onNew: () => {
|
|
2007
2156
|
setListFocus("@new");
|
|
2008
2157
|
setView("new");
|
|
2009
2158
|
}, onClose: adapter.onClose ? close : void 0, components, slots, labels: copy }) : null,
|
|
2010
|
-
opening ? /* @__PURE__ */
|
|
2011
|
-
/* @__PURE__ */
|
|
2012
|
-
/* @__PURE__ */
|
|
2013
|
-
/* @__PURE__ */
|
|
2159
|
+
opening ? /* @__PURE__ */ jsxs7("div", { class: "scui-opening", role: "status", "aria-busy": "true", children: [
|
|
2160
|
+
/* @__PURE__ */ jsx8(HarnessLogo, { id: opening.harness, size: 34 }),
|
|
2161
|
+
/* @__PURE__ */ jsxs7("span", { children: [
|
|
2162
|
+
/* @__PURE__ */ jsxs7("strong", { children: [
|
|
2014
2163
|
"Opening ",
|
|
2015
2164
|
sessionDisplayName(opening)
|
|
2016
2165
|
] }),
|
|
2017
|
-
/* @__PURE__ */
|
|
2166
|
+
/* @__PURE__ */ jsx8("small", { children: "Loading the latest transcript window\u2026" })
|
|
2018
2167
|
] }),
|
|
2019
|
-
/* @__PURE__ */
|
|
2168
|
+
/* @__PURE__ */ jsx8("i", {})
|
|
2020
2169
|
] }) : null,
|
|
2021
|
-
Footer ? /* @__PURE__ */
|
|
2170
|
+
Footer ? /* @__PURE__ */ jsx8(Footer, { state, adapter, value: copy }) : null
|
|
2022
2171
|
] });
|
|
2023
2172
|
}
|
|
2024
2173
|
|
|
2025
2174
|
// src/embed.jsx
|
|
2026
|
-
import { jsx as
|
|
2175
|
+
import { jsx as jsx9 } from "preact/jsx-runtime";
|
|
2027
2176
|
function mountSupercodeMessenger(element, options) {
|
|
2028
2177
|
if (!(element instanceof Element)) throw new TypeError("mountSupercodeMessenger requires an Element");
|
|
2029
2178
|
let state = options.state;
|
|
2030
|
-
const draw = () => render(/* @__PURE__ */
|
|
2179
|
+
const draw = () => render(/* @__PURE__ */ jsx9(SupercodeMessenger, { ...options, state }), element);
|
|
2031
2180
|
options.adapter.onIntent({ action: "mounted" });
|
|
2032
2181
|
draw();
|
|
2033
2182
|
return {
|