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