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