@volter-ai-dev/supercode-ui 0.1.36 → 0.1.38
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 +78 -2
- package/activity.d.ts +2 -0
- package/activity.mjs +941 -0
- package/components.d.ts +4 -0
- package/components.mjs +737 -485
- package/composer.mjs +82 -20
- package/controller.d.ts +4 -0
- package/controller.mjs +22 -2
- package/conversation.mjs +75 -64
- package/core.d.ts +2 -0
- package/core.mjs +85 -2
- package/embed.mjs +338 -149
- package/icon.mjs +1 -1
- package/index.d.ts +66 -2
- package/logo.mjs +11 -6
- package/messenger.mjs +338 -149
- package/package.json +53 -3
- package/react/activity.d.ts +4 -0
- package/react/activity.mjs +941 -0
- package/react/components.mjs +3081 -0
- package/react/composer.d.ts +2 -0
- package/react/composer.mjs +518 -0
- package/react/conversation.d.ts +2 -0
- package/react/conversation.mjs +1330 -0
- package/react/icon.d.ts +2 -0
- package/react/icon.mjs +51 -0
- package/react/index.d.ts +122 -0
- package/react/logo.d.ts +2 -0
- package/react/logo.mjs +92 -0
- package/react/messenger.d.ts +2 -0
- package/react/messenger.mjs +2974 -0
- package/react/sessions.d.ts +2 -0
- package/react/sessions.mjs +429 -0
- package/react/settings.d.ts +2 -0
- package/react/settings.mjs +319 -0
- package/sessions.mjs +48 -28
- package/settings.mjs +170 -69
- package/styles.css +9 -0
package/conversation.mjs
CHANGED
|
@@ -33,6 +33,7 @@ var EMPTY_UI_STATE = Object.freeze({
|
|
|
33
33
|
mode: "none",
|
|
34
34
|
strategy: null,
|
|
35
35
|
canSend: false,
|
|
36
|
+
canSteer: false,
|
|
36
37
|
canResume: false,
|
|
37
38
|
continuationModes: Object.freeze([]),
|
|
38
39
|
canBranch: false,
|
|
@@ -429,6 +430,16 @@ function createToolPresentation(entry) {
|
|
|
429
430
|
function harnessDisplayName(id) {
|
|
430
431
|
return HARNESS_NAMES[id] ?? id;
|
|
431
432
|
}
|
|
433
|
+
var ACTIVITY_PRIORITY = Object.freeze({
|
|
434
|
+
"needs-input": 70,
|
|
435
|
+
failed: 60,
|
|
436
|
+
working: 50,
|
|
437
|
+
unseen: 40,
|
|
438
|
+
finished: 30,
|
|
439
|
+
running: 20,
|
|
440
|
+
recent: 10,
|
|
441
|
+
idle: 0
|
|
442
|
+
});
|
|
432
443
|
function groupConversation(entries) {
|
|
433
444
|
const blocks = [];
|
|
434
445
|
for (const entry of entries) {
|
|
@@ -566,7 +577,7 @@ function Markdown({ value, copyText }) {
|
|
|
566
577
|
}, 1500);
|
|
567
578
|
resets.current.set(button, timer);
|
|
568
579
|
};
|
|
569
|
-
return /* @__PURE__ */ jsx("div", {
|
|
580
|
+
return /* @__PURE__ */ jsx("div", { className: "scui-markdown", "data-copyable": Boolean(copyText), onClick: copyCode, dangerouslySetInnerHTML: { __html: html } });
|
|
570
581
|
}
|
|
571
582
|
|
|
572
583
|
// src/memory.js
|
|
@@ -623,7 +634,7 @@ var ICONS = {
|
|
|
623
634
|
function UiIcon({ name, size = 16, class: className = "" }) {
|
|
624
635
|
const Glyph = ICONS[name];
|
|
625
636
|
if (!Glyph) return null;
|
|
626
|
-
return /* @__PURE__ */ jsx2("svg", {
|
|
637
|
+
return /* @__PURE__ */ jsx2("svg", { className: `scui-icon ${className}`, style: { "--scui-icon-size": `${size}px` }, viewBox: "0 0 18 18", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx2(Glyph, {}) });
|
|
627
638
|
}
|
|
628
639
|
|
|
629
640
|
// src/context.jsx
|
|
@@ -703,7 +714,7 @@ function ImageViewer({ items, index, adapter, onChange, onClose }) {
|
|
|
703
714
|
"dialog",
|
|
704
715
|
{
|
|
705
716
|
ref: dialog,
|
|
706
|
-
|
|
717
|
+
className: "scui-image-viewer",
|
|
707
718
|
"aria-label": `Image preview: ${item.label}`,
|
|
708
719
|
onClose,
|
|
709
720
|
onClick: (event) => {
|
|
@@ -731,19 +742,19 @@ function ImageViewer({ items, index, adapter, onChange, onClose }) {
|
|
|
731
742
|
] })
|
|
732
743
|
] }),
|
|
733
744
|
/* @__PURE__ */ jsxs2("figure", { children: [
|
|
734
|
-
imageUrl ? /* @__PURE__ */ jsx3("img", { src: imageUrl, alt: item.label }) : resolution?.status === "error" ? /* @__PURE__ */ jsxs2("div", {
|
|
745
|
+
imageUrl ? /* @__PURE__ */ jsx3("img", { src: imageUrl, alt: item.label }) : resolution?.status === "error" ? /* @__PURE__ */ jsxs2("div", { className: "scui-image-resolution", role: "alert", children: [
|
|
735
746
|
/* @__PURE__ */ jsx3(UiIcon, { name: "image", size: 28 }),
|
|
736
747
|
/* @__PURE__ */ jsx3("strong", { children: "Could not load image" }),
|
|
737
748
|
/* @__PURE__ */ jsx3("small", { children: resolution.message }),
|
|
738
749
|
/* @__PURE__ */ jsx3("button", { type: "button", onClick: () => resolve(item, true), children: "Retry" })
|
|
739
|
-
] }) : /* @__PURE__ */ jsxs2("div", {
|
|
740
|
-
/* @__PURE__ */ jsx3("i", {
|
|
750
|
+
] }) : /* @__PURE__ */ jsxs2("div", { className: "scui-image-resolution", role: "status", children: [
|
|
751
|
+
/* @__PURE__ */ jsx3("i", { className: "scui-control-spinner" }),
|
|
741
752
|
/* @__PURE__ */ jsx3("strong", { children: "Loading image\u2026" }),
|
|
742
753
|
/* @__PURE__ */ jsx3("small", { children: "The original stays out of the transcript payload." })
|
|
743
754
|
] }),
|
|
744
755
|
items.length > 1 ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
745
|
-
/* @__PURE__ */ jsx3("button", { type: "button",
|
|
746
|
-
/* @__PURE__ */ jsx3("button", { type: "button",
|
|
756
|
+
/* @__PURE__ */ jsx3("button", { type: "button", className: "scui-image-previous", "aria-label": "Previous image", onClick: () => move(-1), children: /* @__PURE__ */ jsx3(UiIcon, { name: "chevron", size: 19 }) }),
|
|
757
|
+
/* @__PURE__ */ jsx3("button", { type: "button", className: "scui-image-next", "aria-label": "Next image", onClick: () => move(1), children: /* @__PURE__ */ jsx3(UiIcon, { name: "chevron", size: 19 }) })
|
|
747
758
|
] }) : null
|
|
748
759
|
] })
|
|
749
760
|
]
|
|
@@ -760,7 +771,7 @@ function MessageImages({ items, adapter }) {
|
|
|
760
771
|
requestAnimationFrame(() => opener.current?.focus({ preventScroll: true }));
|
|
761
772
|
};
|
|
762
773
|
return /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
763
|
-
/* @__PURE__ */ jsx3("div", {
|
|
774
|
+
/* @__PURE__ */ jsx3("div", { className: "scui-message-images", "aria-label": "Message images", children: items.map((item, index) => item.url ? /* @__PURE__ */ jsx3("button", { type: "button", "aria-label": `View image ${item.label}`, onClick: (event) => {
|
|
764
775
|
opener.current = event.currentTarget;
|
|
765
776
|
setActive(viewable.indexOf(item));
|
|
766
777
|
}, children: /* @__PURE__ */ jsx3("img", { src: item.url, alt: "" }) }, item.id ?? `${item.label}:${index}`) : item.reference && adapter?.resolveImage ? /* @__PURE__ */ jsxs2("button", { type: "button", "data-lazy": "true", "aria-label": `Load image ${item.label}`, onClick: (event) => {
|
|
@@ -792,28 +803,28 @@ function LoadingStatus({ state, compact = false }) {
|
|
|
792
803
|
discovering: ["Loading recent sessions", "Scanning native session stores without loading full transcripts.", 2],
|
|
793
804
|
ready: ["Ready", "Coding sessions are up to date.", 3]
|
|
794
805
|
}[state.startup];
|
|
795
|
-
return /* @__PURE__ */ jsxs3("div", {
|
|
796
|
-
/* @__PURE__ */ jsx4("span", {
|
|
797
|
-
/* @__PURE__ */ jsxs3("span", {
|
|
806
|
+
return /* @__PURE__ */ jsxs3("div", { className: `scui-loading${compact ? " scui-loading-compact" : ""}`, role: "status", "aria-busy": state.startup !== "ready", children: [
|
|
807
|
+
/* @__PURE__ */ jsx4("span", { className: "scui-orbit", "aria-hidden": "true", children: /* @__PURE__ */ jsx4("i", {}) }),
|
|
808
|
+
/* @__PURE__ */ jsxs3("span", { className: "scui-loading-copy", children: [
|
|
798
809
|
/* @__PURE__ */ jsx4("strong", { children: copy[0] }),
|
|
799
810
|
/* @__PURE__ */ jsx4("small", { children: copy[1] })
|
|
800
811
|
] }),
|
|
801
|
-
/* @__PURE__ */ jsx4("span", {
|
|
812
|
+
/* @__PURE__ */ jsx4("span", { className: "scui-progress", "aria-hidden": "true", children: [1, 2, 3].map((step) => /* @__PURE__ */ jsx4("i", { "data-progress": step <= copy[2] ? "done" : step === copy[2] + 1 ? "current" : "waiting" }, step)) })
|
|
802
813
|
] });
|
|
803
814
|
}
|
|
804
815
|
function RequestCard({ entry, adapter, canRespond }) {
|
|
805
816
|
const request = entry.request;
|
|
806
817
|
if (!request) return null;
|
|
807
818
|
if (request.status === "responded") {
|
|
808
|
-
return /* @__PURE__ */ jsxs3("div", {
|
|
819
|
+
return /* @__PURE__ */ jsxs3("div", { className: "scui-request-done", children: [
|
|
809
820
|
"\u2713 Request answered \xB7 ",
|
|
810
821
|
request.resolution?.name ?? request.requestKind
|
|
811
822
|
] });
|
|
812
823
|
}
|
|
813
|
-
return /* @__PURE__ */ jsxs3("section", {
|
|
824
|
+
return /* @__PURE__ */ jsxs3("section", { className: "scui-request", role: "alert", "aria-label": `${request.requestKind} needs input`, children: [
|
|
814
825
|
/* @__PURE__ */ jsx4("strong", { children: "Agent needs input" }),
|
|
815
826
|
/* @__PURE__ */ jsx4(Markdown, { value: request.payloadText || entry.text, copyText: adapter?.copyText }),
|
|
816
|
-
/* @__PURE__ */ jsxs3("div", {
|
|
827
|
+
/* @__PURE__ */ jsxs3("div", { className: "scui-request-actions", children: [
|
|
817
828
|
request.options.map((option) => /* @__PURE__ */ jsx4("button", { type: "button", disabled: !canRespond, onClick: () => adapter.onIntent({ action: "respond", requestId: request.requestId, optionId: option.optionId }), children: option.name }, option.optionId)),
|
|
818
829
|
request.cancellable ? /* @__PURE__ */ jsx4("button", { type: "button", disabled: !canRespond, onClick: () => adapter.onIntent({ action: "respond", requestId: request.requestId, optionId: null }), children: "Cancel" }) : null
|
|
819
830
|
] })
|
|
@@ -821,7 +832,7 @@ function RequestCard({ entry, adapter, canRespond }) {
|
|
|
821
832
|
}
|
|
822
833
|
function ContextDisclosure({ context }) {
|
|
823
834
|
if (!context?.length) return null;
|
|
824
|
-
return /* @__PURE__ */ jsxs3("details", {
|
|
835
|
+
return /* @__PURE__ */ jsxs3("details", { className: "scui-context", children: [
|
|
825
836
|
/* @__PURE__ */ jsxs3("summary", { children: [
|
|
826
837
|
"Context \xB7 ",
|
|
827
838
|
context.length
|
|
@@ -850,7 +861,7 @@ function MessageMeta({ entry, adapter }) {
|
|
|
850
861
|
reset.current = setTimeout(() => setCopyState2("idle"), 1500);
|
|
851
862
|
};
|
|
852
863
|
const copyLabel = copyState === "copied" ? "Message copied" : copyState === "failed" ? "Copy failed \xB7 retry" : "Copy message";
|
|
853
|
-
return /* @__PURE__ */ jsxs3("footer", {
|
|
864
|
+
return /* @__PURE__ */ jsxs3("footer", { className: "scui-message-meta", children: [
|
|
854
865
|
validDate ? /* @__PURE__ */ jsx4("time", { dateTime: validDate.toISOString(), title: validDate.toLocaleString(), children: validDate.toLocaleTimeString([], { hour: "numeric", minute: "2-digit" }) }) : null,
|
|
855
866
|
adapter?.copyText && entry.text ? /* @__PURE__ */ jsx4("button", { type: "button", "aria-label": copyLabel, title: copyLabel, onClick: copy, "data-status": copyState, children: /* @__PURE__ */ jsx4(UiIcon, { name: "copy", size: 13 }) }) : null
|
|
856
867
|
] });
|
|
@@ -889,7 +900,7 @@ var TOOL_ICONS = {
|
|
|
889
900
|
};
|
|
890
901
|
function ToolIcon({ category }) {
|
|
891
902
|
const Glyph = TOOL_ICONS[category] ?? TOOL_ICONS.other;
|
|
892
|
-
return /* @__PURE__ */ jsx4("svg", {
|
|
903
|
+
return /* @__PURE__ */ jsx4("svg", { className: "scui-tool-icon", viewBox: "0 0 18 18", fill: "none", stroke: "currentColor", strokeWidth: "1.35", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx4(Glyph, {}) });
|
|
893
904
|
}
|
|
894
905
|
function toolAction2(entry, category, presentation) {
|
|
895
906
|
if (presentation?.action) return presentation.action;
|
|
@@ -944,7 +955,7 @@ function ToolMetrics({ presentation }) {
|
|
|
944
955
|
presentation.exitCode === null ? "" : `exit ${presentation.exitCode}`,
|
|
945
956
|
formatDuration(presentation.durationMs)
|
|
946
957
|
].filter(Boolean);
|
|
947
|
-
return metrics.length ? /* @__PURE__ */ jsx4("div", {
|
|
958
|
+
return metrics.length ? /* @__PURE__ */ jsx4("div", { className: "scui-tool-metrics", children: metrics.map((metric) => /* @__PURE__ */ jsx4("span", { children: metric }, metric)) }) : null;
|
|
948
959
|
}
|
|
949
960
|
function PendingElapsed({ now }) {
|
|
950
961
|
const clock = now ?? Date.now;
|
|
@@ -954,11 +965,11 @@ function PendingElapsed({ now }) {
|
|
|
954
965
|
const timer = setInterval(() => setElapsed(Math.max(0, clock() - started.current)), 1e3);
|
|
955
966
|
return () => clearInterval(timer);
|
|
956
967
|
}, [clock]);
|
|
957
|
-
return /* @__PURE__ */ jsx4("small", {
|
|
968
|
+
return /* @__PURE__ */ jsx4("small", { className: "scui-tool-elapsed", children: elapsed < 1e3 ? "now" : formatDuration(elapsed) });
|
|
958
969
|
}
|
|
959
970
|
function LinePreview({ value, kind }) {
|
|
960
971
|
if (!value) return null;
|
|
961
|
-
return /* @__PURE__ */ jsx4("ol", {
|
|
972
|
+
return /* @__PURE__ */ jsx4("ol", { className: "scui-code-preview", "data-kind": kind, children: stripAnsi(value).split("\n").map((line, index) => {
|
|
962
973
|
const tone = kind === "diff" ? line.startsWith("+") && !line.startsWith("+++") ? "add" : line.startsWith("-") && !line.startsWith("---") ? "remove" : line.startsWith("@@") ? "hunk" : "plain" : "plain";
|
|
963
974
|
return /* @__PURE__ */ jsxs3("li", { "data-tone": tone, children: [
|
|
964
975
|
/* @__PURE__ */ jsx4("span", { children: index + 1 }),
|
|
@@ -967,7 +978,7 @@ function LinePreview({ value, kind }) {
|
|
|
967
978
|
}) });
|
|
968
979
|
}
|
|
969
980
|
function TerminalPreview({ presentation, pending, failed }) {
|
|
970
|
-
return /* @__PURE__ */ jsxs3("section", {
|
|
981
|
+
return /* @__PURE__ */ jsxs3("section", { className: "scui-terminal", children: [
|
|
971
982
|
/* @__PURE__ */ jsxs3("header", { children: [
|
|
972
983
|
/* @__PURE__ */ jsxs3("span", { "aria-hidden": "true", children: [
|
|
973
984
|
/* @__PURE__ */ jsx4("i", {}),
|
|
@@ -976,15 +987,15 @@ function TerminalPreview({ presentation, pending, failed }) {
|
|
|
976
987
|
] }),
|
|
977
988
|
/* @__PURE__ */ jsx4("code", { children: presentation.command ? `$ ${presentation.command}` : "Terminal" })
|
|
978
989
|
] }),
|
|
979
|
-
presentation.preview ? /* @__PURE__ */ jsx4("pre", { "data-error": failed, children: stripAnsi(presentation.preview) }) : pending ? /* @__PURE__ */ jsxs3("div", {
|
|
990
|
+
presentation.preview ? /* @__PURE__ */ jsx4("pre", { "data-error": failed, children: stripAnsi(presentation.preview) }) : pending ? /* @__PURE__ */ jsxs3("div", { className: "scui-terminal-wait", children: [
|
|
980
991
|
/* @__PURE__ */ jsx4("i", {}),
|
|
981
992
|
" Waiting for output"
|
|
982
|
-
] }) : /* @__PURE__ */ jsx4("div", {
|
|
993
|
+
] }) : /* @__PURE__ */ jsx4("div", { className: "scui-terminal-empty", children: "No output" })
|
|
983
994
|
] });
|
|
984
995
|
}
|
|
985
996
|
function SearchPreview({ presentation }) {
|
|
986
997
|
const lines = stripAnsi(presentation.preview).split("\n").filter(Boolean);
|
|
987
|
-
return /* @__PURE__ */ jsxs3("section", {
|
|
998
|
+
return /* @__PURE__ */ jsxs3("section", { className: "scui-search-preview", children: [
|
|
988
999
|
presentation.query ? /* @__PURE__ */ jsxs3("header", { children: [
|
|
989
1000
|
/* @__PURE__ */ jsx4("span", { children: "Search" }),
|
|
990
1001
|
/* @__PURE__ */ jsx4("code", { children: presentation.query })
|
|
@@ -1006,22 +1017,22 @@ function ToolPreview({ presentation, entry }) {
|
|
|
1006
1017
|
const pending = entry.status === "pending";
|
|
1007
1018
|
const failed = entry.status === "error";
|
|
1008
1019
|
if (presentation.detail === "terminal") return /* @__PURE__ */ jsx4(TerminalPreview, { presentation, pending, failed });
|
|
1009
|
-
if (presentation.detail === "diff") return presentation.preview ? /* @__PURE__ */ jsx4(LinePreview, { value: presentation.preview, kind: "diff" }) : /* @__PURE__ */ jsx4("div", {
|
|
1010
|
-
if (presentation.detail === "file") return presentation.preview ? /* @__PURE__ */ jsx4(LinePreview, { value: presentation.preview, kind: "file" }) : /* @__PURE__ */ jsx4("div", {
|
|
1020
|
+
if (presentation.detail === "diff") return presentation.preview ? /* @__PURE__ */ jsx4(LinePreview, { value: presentation.preview, kind: "diff" }) : /* @__PURE__ */ jsx4("div", { className: "scui-tool-empty", children: "Edit completed without a textual diff" });
|
|
1021
|
+
if (presentation.detail === "file") return presentation.preview ? /* @__PURE__ */ jsx4(LinePreview, { value: presentation.preview, kind: "file" }) : /* @__PURE__ */ jsx4("div", { className: "scui-tool-empty", children: "File contents were not included in this event" });
|
|
1011
1022
|
if (presentation.detail === "matches") return /* @__PURE__ */ jsx4(SearchPreview, { presentation });
|
|
1012
|
-
if (presentation.detail === "web") return /* @__PURE__ */ jsxs3("section", {
|
|
1023
|
+
if (presentation.detail === "web") return /* @__PURE__ */ jsxs3("section", { className: "scui-web-preview", children: [
|
|
1013
1024
|
presentation.url ? /* @__PURE__ */ jsx4("code", { children: presentation.url }) : null,
|
|
1014
1025
|
presentation.preview ? /* @__PURE__ */ jsx4("p", { children: stripAnsi(presentation.preview) }) : /* @__PURE__ */ jsx4("small", { children: pending ? "Waiting for the page" : "No page summary returned" })
|
|
1015
1026
|
] });
|
|
1016
|
-
if (presentation.detail === "agent") return /* @__PURE__ */ jsx4("section", {
|
|
1027
|
+
if (presentation.detail === "agent") return /* @__PURE__ */ jsx4("section", { className: "scui-agent-preview", children: presentation.items?.length ? /* @__PURE__ */ jsx4("ol", { className: "scui-agent-roster", children: presentation.items.map((item, index) => /* @__PURE__ */ jsxs3("li", { children: [
|
|
1017
1028
|
/* @__PURE__ */ jsx4("strong", { children: item.label }),
|
|
1018
1029
|
/* @__PURE__ */ jsx4("small", { children: item.status })
|
|
1019
1030
|
] }, `${item.label}:${index}`)) }) : presentation.preview ? /* @__PURE__ */ jsx4("pre", { children: stripAnsi(presentation.preview) }) : /* @__PURE__ */ jsx4("small", { children: pending ? "Agent is working" : "No textual handoff returned" }) });
|
|
1020
|
-
if (presentation.detail === "plan") return /* @__PURE__ */ jsx4("ol", {
|
|
1031
|
+
if (presentation.detail === "plan") return /* @__PURE__ */ jsx4("ol", { className: "scui-plan-preview", children: presentation.items?.map((item, index) => /* @__PURE__ */ jsxs3("li", { "data-status": item.status, children: [
|
|
1021
1032
|
/* @__PURE__ */ jsx4("i", { "aria-hidden": "true" }),
|
|
1022
1033
|
/* @__PURE__ */ jsx4("span", { children: item.label })
|
|
1023
1034
|
] }, `${item.label}:${index}`)) });
|
|
1024
|
-
return presentation.preview ? /* @__PURE__ */ jsx4("pre", {
|
|
1035
|
+
return presentation.preview ? /* @__PURE__ */ jsx4("pre", { className: "scui-tool-output", "data-error": failed, children: stripAnsi(presentation.preview) }) : null;
|
|
1025
1036
|
}
|
|
1026
1037
|
function ToolActions({ presentation, adapter }) {
|
|
1027
1038
|
const [copied, setCopied] = useState2(false);
|
|
@@ -1035,15 +1046,15 @@ function ToolActions({ presentation, adapter }) {
|
|
|
1035
1046
|
clearTimeout(reset.current);
|
|
1036
1047
|
reset.current = setTimeout(() => setCopied(false), 1500);
|
|
1037
1048
|
};
|
|
1038
|
-
return action ? /* @__PURE__ */ jsx4("div", {
|
|
1049
|
+
return action ? /* @__PURE__ */ jsx4("div", { className: "scui-tool-actions", children: /* @__PURE__ */ jsx4("button", { type: "button", onClick: copy, children: copied ? "Copied" : action[0] }) }) : null;
|
|
1039
1050
|
}
|
|
1040
1051
|
function ToolStack({ tools }) {
|
|
1041
1052
|
if (tools.length < 2) return null;
|
|
1042
|
-
return /* @__PURE__ */ jsx4("div", {
|
|
1053
|
+
return /* @__PURE__ */ jsx4("div", { className: "scui-tool-stack", "aria-label": "Coordinated tools", children: tools.map((tool) => /* @__PURE__ */ jsx4("span", { children: tool.replaceAll("__", " \xB7 ").replaceAll("_", " ") }, tool)) });
|
|
1043
1054
|
}
|
|
1044
1055
|
function TechnicalDetails({ entry }) {
|
|
1045
1056
|
if (!entry.arguments && !entry.resultText) return null;
|
|
1046
|
-
return /* @__PURE__ */ jsxs3("details", {
|
|
1057
|
+
return /* @__PURE__ */ jsxs3("details", { className: "scui-tool-technical", children: [
|
|
1047
1058
|
/* @__PURE__ */ jsx4("summary", { children: "Technical details" }),
|
|
1048
1059
|
/* @__PURE__ */ jsxs3("div", { children: [
|
|
1049
1060
|
entry.arguments ? /* @__PURE__ */ jsxs3("section", { children: [
|
|
@@ -1066,17 +1077,17 @@ function TechnicalDetails({ entry }) {
|
|
|
1066
1077
|
function TranscriptEntry({ entry, state, adapter }) {
|
|
1067
1078
|
if (entry.role === "request") return /* @__PURE__ */ jsx4(RequestCard, { entry, adapter, canRespond: state.canRespond });
|
|
1068
1079
|
if (entry.role === "reasoning") {
|
|
1069
|
-
return /* @__PURE__ */ jsxs3("details", {
|
|
1080
|
+
return /* @__PURE__ */ jsxs3("details", { className: "scui-reasoning", open: entry.streaming, children: [
|
|
1070
1081
|
/* @__PURE__ */ jsx4("summary", { children: entry.streaming ? "Reasoning\u2026" : "Reasoning" }),
|
|
1071
1082
|
/* @__PURE__ */ jsx4(Markdown, { value: entry.text, copyText: adapter?.copyText })
|
|
1072
1083
|
] });
|
|
1073
1084
|
}
|
|
1074
|
-
if (entry.role === "notice" || entry.role === "system") return /* @__PURE__ */ jsx4("div", {
|
|
1075
|
-
return /* @__PURE__ */ jsxs3("article", {
|
|
1085
|
+
if (entry.role === "notice" || entry.role === "system") return /* @__PURE__ */ jsx4("div", { className: "scui-notice", "data-code": entry.code, children: entry.text });
|
|
1086
|
+
return /* @__PURE__ */ jsxs3("article", { className: "scui-message", "data-role": entry.role, "aria-label": `${entry.role === "user" ? "Your" : "Assistant"} message`, children: [
|
|
1076
1087
|
/* @__PURE__ */ jsx4(MessageImages, { items: entry.images, adapter }),
|
|
1077
1088
|
/* @__PURE__ */ jsx4(Markdown, { value: entry.text, copyText: adapter?.copyText }),
|
|
1078
1089
|
/* @__PURE__ */ jsx4(ContextDisclosure, { context: entry.context }),
|
|
1079
|
-
entry.truncated ? /* @__PURE__ */ jsx4("small", {
|
|
1090
|
+
entry.truncated ? /* @__PURE__ */ jsx4("small", { className: "scui-truncated", children: "Entry truncated by host \xB7 load native session for the complete value" }) : null,
|
|
1080
1091
|
/* @__PURE__ */ jsx4(MessageMeta, { entry, adapter })
|
|
1081
1092
|
] });
|
|
1082
1093
|
}
|
|
@@ -1092,20 +1103,20 @@ function ToolRow({ entry, workspace, open = false, adapter }) {
|
|
|
1092
1103
|
const summary = /* @__PURE__ */ jsxs3(Fragment4, { children: [
|
|
1093
1104
|
/* @__PURE__ */ jsx4(ToolIcon, { category }),
|
|
1094
1105
|
/* @__PURE__ */ jsx4("strong", { children: toolAction2(entry, category, presentation) }),
|
|
1095
|
-
target ? /* @__PURE__ */ jsx4("code", {
|
|
1096
|
-
/* @__PURE__ */ jsx4("span", {
|
|
1106
|
+
target ? /* @__PURE__ */ jsx4("code", { className: "scui-tool-target", title: presentation.target, children: target }) : null,
|
|
1107
|
+
/* @__PURE__ */ jsx4("span", { className: "scui-spacer" }),
|
|
1097
1108
|
entry.status === "pending" ? /* @__PURE__ */ jsx4(PendingElapsed, { now: adapter?.now }) : null,
|
|
1098
|
-
/* @__PURE__ */ jsx4("span", {
|
|
1099
|
-
hasDetail ? /* @__PURE__ */ jsx4(UiIcon, { name: "chevron", size: 14,
|
|
1109
|
+
/* @__PURE__ */ jsx4("span", { className: "scui-tool-status", role: "status", "data-status": entry.status ?? "completed", "aria-label": entry.status ?? "completed", children: entry.status === "pending" ? /* @__PURE__ */ jsx4("i", {}) : /* @__PURE__ */ jsx4(UiIcon, { name: entry.status === "error" ? "close" : "check", size: 12 }) }),
|
|
1110
|
+
hasDetail ? /* @__PURE__ */ jsx4(UiIcon, { name: "chevron", size: 14, className: "scui-tool-chevron" }) : null
|
|
1100
1111
|
] });
|
|
1101
|
-
if (!hasDetail) return /* @__PURE__ */ jsx4("div", {
|
|
1102
|
-
return /* @__PURE__ */ jsxs3("details", {
|
|
1103
|
-
/* @__PURE__ */ jsx4("summary", {
|
|
1104
|
-
/* @__PURE__ */ jsxs3("div", {
|
|
1112
|
+
if (!hasDetail) return /* @__PURE__ */ jsx4("div", { className: "scui-tool", "data-status": entry.status ?? "completed", "data-category": category, children: /* @__PURE__ */ jsx4("div", { className: "scui-tool-head", children: summary }) });
|
|
1113
|
+
return /* @__PURE__ */ jsxs3("details", { className: "scui-tool", "data-status": entry.status ?? "completed", "data-category": category, open: expanded, onToggle: (event) => setExpanded(event.currentTarget.open), children: [
|
|
1114
|
+
/* @__PURE__ */ jsx4("summary", { className: "scui-tool-head", children: summary }),
|
|
1115
|
+
/* @__PURE__ */ jsxs3("div", { className: "scui-tool-detail", children: [
|
|
1105
1116
|
/* @__PURE__ */ jsx4(ToolMetrics, { presentation }),
|
|
1106
1117
|
/* @__PURE__ */ jsx4(ToolStack, { tools: presentation.tools ?? [] }),
|
|
1107
1118
|
/* @__PURE__ */ jsx4(ToolPreview, { presentation, entry }),
|
|
1108
|
-
presentation.fields.length ? /* @__PURE__ */ jsx4("dl", {
|
|
1119
|
+
presentation.fields.length ? /* @__PURE__ */ jsx4("dl", { className: "scui-tool-fields", children: presentation.fields.map((field) => /* @__PURE__ */ jsxs3("div", { children: [
|
|
1109
1120
|
/* @__PURE__ */ jsx4("dt", { children: field.label }),
|
|
1110
1121
|
/* @__PURE__ */ jsx4("dd", { children: field.value })
|
|
1111
1122
|
] }, field.label)) }) : null,
|
|
@@ -1115,18 +1126,18 @@ function ToolRow({ entry, workspace, open = false, adapter }) {
|
|
|
1115
1126
|
] });
|
|
1116
1127
|
}
|
|
1117
1128
|
function ActivityGroup({ entries, state, adapter }) {
|
|
1118
|
-
if (entries.length === 1) return /* @__PURE__ */ jsx4("section", {
|
|
1129
|
+
if (entries.length === 1) return /* @__PURE__ */ jsx4("section", { className: "scui-activity", "data-single": "true", children: /* @__PURE__ */ jsx4(ToolRow, { entry: entries[0], workspace: state.workspace, adapter }) });
|
|
1119
1130
|
const active = entries.some((entry) => entry.status === "pending");
|
|
1120
1131
|
const [open, setOpen] = useState2(active);
|
|
1121
1132
|
const id = useId();
|
|
1122
1133
|
useEffect3(() => {
|
|
1123
1134
|
if (active) setOpen(true);
|
|
1124
1135
|
}, [active]);
|
|
1125
|
-
return /* @__PURE__ */ jsxs3("section", {
|
|
1126
|
-
/* @__PURE__ */ jsxs3("button", {
|
|
1127
|
-
/* @__PURE__ */ jsx4("span", {
|
|
1136
|
+
return /* @__PURE__ */ jsxs3("section", { className: "scui-activity", children: [
|
|
1137
|
+
/* @__PURE__ */ jsxs3("button", { className: "scui-activity-head", type: "button", "aria-expanded": open, "aria-controls": id, onClick: () => setOpen((value) => !value), children: [
|
|
1138
|
+
/* @__PURE__ */ jsx4("span", { className: "scui-fold", "data-open": open, children: /* @__PURE__ */ jsx4(UiIcon, { name: "chevron", size: 14 }) }),
|
|
1128
1139
|
/* @__PURE__ */ jsx4("strong", { children: activitySummary(entries) }),
|
|
1129
|
-
/* @__PURE__ */ jsx4("span", {
|
|
1140
|
+
/* @__PURE__ */ jsx4("span", { className: "scui-spacer" }),
|
|
1130
1141
|
/* @__PURE__ */ jsxs3("small", { children: [
|
|
1131
1142
|
entries.filter((entry) => entry.status !== "pending").length,
|
|
1132
1143
|
"/",
|
|
@@ -1139,7 +1150,7 @@ function ActivityGroup({ entries, state, adapter }) {
|
|
|
1139
1150
|
function TaskPlan({ plan }) {
|
|
1140
1151
|
if (!plan.items.length) return null;
|
|
1141
1152
|
const complete = plan.items.filter((item) => item.status === "completed" || item.status === "cancelled").length;
|
|
1142
|
-
return /* @__PURE__ */ jsxs3("details", {
|
|
1153
|
+
return /* @__PURE__ */ jsxs3("details", { className: "scui-plan", children: [
|
|
1143
1154
|
/* @__PURE__ */ jsxs3("summary", { children: [
|
|
1144
1155
|
/* @__PURE__ */ jsx4("span", { children: "Plan" }),
|
|
1145
1156
|
/* @__PURE__ */ jsxs3("small", { children: [
|
|
@@ -1157,7 +1168,7 @@ function TaskPlan({ plan }) {
|
|
|
1157
1168
|
}
|
|
1158
1169
|
function SessionDetails({ semantics }) {
|
|
1159
1170
|
if (!semantics.fidelity && !semantics.residueCount && !semantics.parseErrors && !semantics.subagents.length) return null;
|
|
1160
|
-
return /* @__PURE__ */ jsxs3("details", {
|
|
1171
|
+
return /* @__PURE__ */ jsxs3("details", { className: "scui-details", children: [
|
|
1161
1172
|
/* @__PURE__ */ jsx4("summary", { children: "Session details" }),
|
|
1162
1173
|
/* @__PURE__ */ jsxs3("div", { children: [
|
|
1163
1174
|
semantics.fidelity ? /* @__PURE__ */ jsxs3("p", { children: [
|
|
@@ -1203,7 +1214,7 @@ function ConversationAnnouncements({ state }) {
|
|
|
1203
1214
|
}
|
|
1204
1215
|
previousBusy.current = state.busy;
|
|
1205
1216
|
}, [state.busy, state.error, state.harness]);
|
|
1206
|
-
return /* @__PURE__ */ jsx4("span", {
|
|
1217
|
+
return /* @__PURE__ */ jsx4("span", { className: "scui-sr-only", role: "status", "aria-live": "polite", "aria-atomic": "true", children: announcement });
|
|
1207
1218
|
}
|
|
1208
1219
|
function Conversation({ state, adapter, components = {}, slots = {}, memoryKey = state.attached?.key || `${state.harness}:${state.workspace}`, pending = null, unreadAfterMessages = null }) {
|
|
1209
1220
|
const scroller = useRef3(null);
|
|
@@ -1252,9 +1263,9 @@ function Conversation({ state, adapter, components = {}, slots = {}, memoryKey =
|
|
|
1252
1263
|
else pin();
|
|
1253
1264
|
} else if (atBottom) pin();
|
|
1254
1265
|
}, [memoryKey, state.transcript, state.busy, state.operation, state.error, pendingMessage?.text, pendingMessage?.status]);
|
|
1255
|
-
return /* @__PURE__ */ jsxs3("div", {
|
|
1266
|
+
return /* @__PURE__ */ jsxs3("div", { className: "scui-conversation-wrap", children: [
|
|
1256
1267
|
/* @__PURE__ */ jsx4(ConversationAnnouncements, { state }),
|
|
1257
|
-
/* @__PURE__ */ jsx4("div", {
|
|
1268
|
+
/* @__PURE__ */ jsx4("div", { className: "scui-conversation", ref: scroller, tabIndex: 0, "aria-label": "Conversation", onScroll: (event) => {
|
|
1258
1269
|
const element = event.currentTarget;
|
|
1259
1270
|
const bottom = element.scrollHeight - element.scrollTop - element.clientHeight <= 64;
|
|
1260
1271
|
setAtBottom(bottom);
|
|
@@ -1263,19 +1274,19 @@ function Conversation({ state, adapter, components = {}, slots = {}, memoryKey =
|
|
|
1263
1274
|
Before ? /* @__PURE__ */ jsx4(Before, { state, adapter, value: null }) : null,
|
|
1264
1275
|
/* @__PURE__ */ jsx4(Plan, { plan: state.taskPlan, value: state.taskPlan, state, adapter }),
|
|
1265
1276
|
/* @__PURE__ */ jsx4(SessionDetails, { semantics: state.semantics }),
|
|
1266
|
-
state.history.hasEarlier ? /* @__PURE__ */ jsx4("button", {
|
|
1277
|
+
state.history.hasEarlier ? /* @__PURE__ */ jsx4("button", { className: "scui-load", type: "button", disabled: Boolean(state.operation), onClick: () => {
|
|
1267
1278
|
const element = scroller.current;
|
|
1268
1279
|
if (element) earlierAnchor.current = { height: element.scrollHeight, top: element.scrollTop, entries: state.transcript.length, firstId: state.transcript[0]?.id, seenOperation: false };
|
|
1269
1280
|
setAtBottom(false);
|
|
1270
1281
|
adapter.onIntent({ action: "loadEarlier" });
|
|
1271
1282
|
}, children: "Load earlier messages" }) : null,
|
|
1272
1283
|
!blocks.length && state.startup !== "ready" ? /* @__PURE__ */ jsx4(LoadingStatus, { state }) : null,
|
|
1273
|
-
!blocks.length && state.startup === "ready" ? Empty ? /* @__PURE__ */ jsx4(Empty, { state, adapter, value: null }) : /* @__PURE__ */ jsx4("div", {
|
|
1284
|
+
!blocks.length && state.startup === "ready" ? Empty ? /* @__PURE__ */ jsx4(Empty, { state, adapter, value: null }) : /* @__PURE__ */ jsx4("div", { className: "scui-empty", children: state.error ?? (state.harness ? `${harnessDisplayName(state.harness)} is listening. Say something.` : "No transcript yet.") }) : null,
|
|
1274
1285
|
blocks.map((block, index) => /* @__PURE__ */ jsxs3(Fragment3, { children: [
|
|
1275
|
-
index === unreadBlock ? /* @__PURE__ */ jsx4("div", {
|
|
1286
|
+
index === unreadBlock ? /* @__PURE__ */ jsx4("div", { className: "scui-unread-divider", role: "separator", "aria-label": "New messages", children: /* @__PURE__ */ jsx4("span", { children: "New" }) }) : null,
|
|
1276
1287
|
block.kind === "activity" ? /* @__PURE__ */ jsx4(Group, { value: block.entries, entries: block.entries, state, adapter }) : /* @__PURE__ */ jsx4(Entry, { value: block.entry, entry: block.entry, state, adapter })
|
|
1277
1288
|
] }, block.id)),
|
|
1278
|
-
pendingMessage ? /* @__PURE__ */ jsxs3("article", {
|
|
1289
|
+
pendingMessage ? /* @__PURE__ */ jsxs3("article", { className: "scui-message scui-pending", "data-role": "user", "data-status": pendingMessage.status, "aria-label": "Your pending message", children: [
|
|
1279
1290
|
/* @__PURE__ */ jsx4(MessageImages, { items: pendingMessage.images, adapter }),
|
|
1280
1291
|
/* @__PURE__ */ jsx4(Markdown, { value: pendingMessage.text, copyText: adapter?.copyText }),
|
|
1281
1292
|
/* @__PURE__ */ jsx4(ContextDisclosure, { context: pendingMessage.context }),
|
|
@@ -1287,7 +1298,7 @@ function Conversation({ state, adapter, components = {}, slots = {}, memoryKey =
|
|
|
1287
1298
|
] }) : null
|
|
1288
1299
|
] })
|
|
1289
1300
|
] }) : null,
|
|
1290
|
-
state.busy ? /* @__PURE__ */ jsxs3("div", {
|
|
1301
|
+
state.busy ? /* @__PURE__ */ jsxs3("div", { className: "scui-working", role: "status", children: [
|
|
1291
1302
|
/* @__PURE__ */ jsx4("span", { "aria-hidden": "true", children: "\u2726" }),
|
|
1292
1303
|
/* @__PURE__ */ jsx4("i", {}),
|
|
1293
1304
|
/* @__PURE__ */ jsx4("i", {}),
|
|
@@ -1299,7 +1310,7 @@ function Conversation({ state, adapter, components = {}, slots = {}, memoryKey =
|
|
|
1299
1310
|
] }) : null,
|
|
1300
1311
|
After ? /* @__PURE__ */ jsx4(After, { state, adapter, value: null }) : null
|
|
1301
1312
|
] }) }),
|
|
1302
|
-
!atBottom ? /* @__PURE__ */ jsxs3("button", {
|
|
1313
|
+
!atBottom ? /* @__PURE__ */ jsxs3("button", { className: "scui-latest", type: "button", onClick: pin, children: [
|
|
1303
1314
|
/* @__PURE__ */ jsx4(UiIcon, { name: "down", size: 13 }),
|
|
1304
1315
|
" Latest"
|
|
1305
1316
|
] }) : null
|
package/core.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export type {
|
|
2
2
|
AttachedSessionModel,
|
|
3
|
+
AgentActivityModel,
|
|
3
4
|
ContinuationMode,
|
|
4
5
|
ControlStrategy,
|
|
5
6
|
HarnessId,
|
|
@@ -37,6 +38,7 @@ export {
|
|
|
37
38
|
isSendKey,
|
|
38
39
|
normalizeUiState,
|
|
39
40
|
operationLabel,
|
|
41
|
+
projectAgentActivity,
|
|
40
42
|
parseSupercodeUiIntent,
|
|
41
43
|
relativeAge,
|
|
42
44
|
sessionActivity,
|
package/core.mjs
CHANGED
|
@@ -30,6 +30,7 @@ export const EMPTY_UI_STATE = Object.freeze({
|
|
|
30
30
|
mode: 'none',
|
|
31
31
|
strategy: null,
|
|
32
32
|
canSend: false,
|
|
33
|
+
canSteer: false,
|
|
33
34
|
canResume: false,
|
|
34
35
|
continuationModes: Object.freeze([]),
|
|
35
36
|
canBranch: false,
|
|
@@ -771,6 +772,7 @@ export function normalizeUiState(value) {
|
|
|
771
772
|
mode: MODES.has(raw.mode) ? raw.mode : 'none',
|
|
772
773
|
strategy: STRATEGIES.has(raw.strategy) ? raw.strategy : null,
|
|
773
774
|
canSend: raw.canSend === true,
|
|
775
|
+
canSteer: raw.canSteer === true,
|
|
774
776
|
canResume,
|
|
775
777
|
continuationModes,
|
|
776
778
|
canBranch: raw.canBranch === true,
|
|
@@ -804,7 +806,29 @@ export function normalizeUiState(value) {
|
|
|
804
806
|
const preferredLaunchMode = launchModes.includes(item.preferredLaunchMode)
|
|
805
807
|
? item.preferredLaunchMode
|
|
806
808
|
: launchModes[0] ?? null;
|
|
807
|
-
|
|
809
|
+
const capabilities = record(item.capabilities);
|
|
810
|
+
return [{
|
|
811
|
+
id: item.id,
|
|
812
|
+
label: string(item.label, harnessDisplayName(item.id)),
|
|
813
|
+
installed: item.installed === true,
|
|
814
|
+
startable,
|
|
815
|
+
reason: typeof item.reason === 'string' ? boundedString(item.reason) : null,
|
|
816
|
+
auth: ['ready', 'configured', 'required', 'unknown'].includes(item.auth) ? item.auth : 'unknown',
|
|
817
|
+
runtime: ['ready', 'degraded', 'unavailable'].includes(item.runtime) ? item.runtime : startable ? 'ready' : 'unavailable',
|
|
818
|
+
protocol: boundedString(item.protocol, 100),
|
|
819
|
+
repair: typeof item.repair === 'string' ? boundedString(item.repair, 4_000) : null,
|
|
820
|
+
capabilities: {
|
|
821
|
+
start: capabilities?.start === true,
|
|
822
|
+
resume: capabilities?.resume === true,
|
|
823
|
+
attach: capabilities?.attach === true,
|
|
824
|
+
send: capabilities?.send === true,
|
|
825
|
+
interrupt: capabilities?.interrupt === true,
|
|
826
|
+
steer: capabilities?.steer === true,
|
|
827
|
+
respond: capabilities?.respond === true,
|
|
828
|
+
},
|
|
829
|
+
launchModes,
|
|
830
|
+
preferredLaunchMode,
|
|
831
|
+
}];
|
|
808
832
|
}) : [],
|
|
809
833
|
history: { sessionLimit: number(history?.sessionLimit), hasMoreSessions: history?.hasMoreSessions === true, transcriptLimit: number(history?.transcriptLimit, 120), hasEarlier: history?.hasEarlier === true },
|
|
810
834
|
savedDraft: string(raw.savedDraft),
|
|
@@ -843,6 +867,60 @@ export function sessionActivity(state, row) {
|
|
|
843
867
|
return 'idle';
|
|
844
868
|
}
|
|
845
869
|
|
|
870
|
+
const ACTIVITY_PRIORITY = Object.freeze({
|
|
871
|
+
'needs-input': 70,
|
|
872
|
+
failed: 60,
|
|
873
|
+
working: 50,
|
|
874
|
+
unseen: 40,
|
|
875
|
+
finished: 30,
|
|
876
|
+
running: 20,
|
|
877
|
+
recent: 10,
|
|
878
|
+
idle: 0,
|
|
879
|
+
});
|
|
880
|
+
|
|
881
|
+
function activityDetail(activity, preview, pill) {
|
|
882
|
+
if (preview) return preview;
|
|
883
|
+
if (activity === 'needs-input') return 'Needs input';
|
|
884
|
+
if (activity === 'failed') return 'Run failed';
|
|
885
|
+
if (activity === 'working') return 'Working…';
|
|
886
|
+
if (activity === 'finished') return 'Finished';
|
|
887
|
+
if (activity === 'unseen') return 'New reply';
|
|
888
|
+
if (activity === 'running') return 'Session is running';
|
|
889
|
+
return pill || 'Agent chats';
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
/** A stable, host-agnostic projection for overlay launchers and compact activity trays. */
|
|
893
|
+
export function projectAgentActivity(value) {
|
|
894
|
+
const state = normalizeUiState(value);
|
|
895
|
+
const attentionByKey = new Map(state.attention.map((item) => [item.key, item]));
|
|
896
|
+
const unreadCount = state.attention.reduce((total, item) => total + (item.unreadCount ?? 1), 0);
|
|
897
|
+
const ranked = state.sessions.map((row, index) => {
|
|
898
|
+
const activity = sessionActivity(state, row);
|
|
899
|
+
return {
|
|
900
|
+
row,
|
|
901
|
+
index,
|
|
902
|
+
activity,
|
|
903
|
+
priority: ACTIVITY_PRIORITY[activity] ?? 0,
|
|
904
|
+
active: row.active || row.key === state.attached?.key || row.key === state.owned?.key,
|
|
905
|
+
updatedAt: row.previewUpdatedAt ?? row.updatedAt ?? 0,
|
|
906
|
+
};
|
|
907
|
+
}).sort((left, right) => right.priority - left.priority || Number(right.active) - Number(left.active) || right.updatedAt - left.updatedAt || left.index - right.index);
|
|
908
|
+
const selected = ranked[0];
|
|
909
|
+
const fallback = state.attached ?? state.owned;
|
|
910
|
+
const harness = selected?.row.harness ?? fallback?.harness ?? state.harness;
|
|
911
|
+
const activity = selected?.activity ?? (state.needsInput ? 'needs-input' : state.busy ? 'working' : state.startup === 'ready' ? 'idle' : 'recent');
|
|
912
|
+
const attention = selected ? attentionByKey.get(selected.row.key) : null;
|
|
913
|
+
const preview = selected?.row.preview || attention?.preview || '';
|
|
914
|
+
return {
|
|
915
|
+
harness,
|
|
916
|
+
sessionKey: selected?.row.key ?? fallback?.key ?? null,
|
|
917
|
+
title: selected ? sessionDisplayName(selected.row) : fallback ? sessionDisplayName(fallback) : 'Agent chats',
|
|
918
|
+
detail: activityDetail(activity, preview, state.pill.label),
|
|
919
|
+
activity,
|
|
920
|
+
unreadCount,
|
|
921
|
+
};
|
|
922
|
+
}
|
|
923
|
+
|
|
846
924
|
export function filterSessions(rows, query) {
|
|
847
925
|
const needle = query.trim().toLocaleLowerCase();
|
|
848
926
|
if (!needle) return [...rows];
|
|
@@ -908,7 +986,7 @@ export function canContinueHere(state) {
|
|
|
908
986
|
|
|
909
987
|
export function operationLabel(operation) {
|
|
910
988
|
if (!operation) return '';
|
|
911
|
-
const labels = { discover: 'Refreshing chats…', observe: 'Loading recent messages…', attach: 'Opening chat…', start: 'Starting new chat…', resume: 'Continuing here…', join: 'Joining live session…', detach: 'Detaching to read-only…', branch: 'Starting continuation…', reduce: 'Reducing context and verifying reversibility…', terminal: 'Preparing terminal handoff…', export: 'Exporting losslessly…', interrupt: 'Stopping agent…', respond: 'Sending response…', configureHarness: 'Updating harness settings…', loadEarlier: 'Loading earlier messages…', loadSessions: 'Loading more chats…', refresh: 'Retrying…' };
|
|
989
|
+
const labels = { discover: 'Refreshing chats…', observe: 'Loading recent messages…', attach: 'Opening chat…', start: 'Starting new chat…', resume: 'Continuing here…', join: 'Joining live session…', detach: 'Detaching to read-only…', branch: 'Starting continuation…', reduce: 'Reducing context and verifying reversibility…', terminal: 'Preparing terminal handoff…', export: 'Exporting losslessly…', steer: 'Steering agent…', interrupt: 'Stopping agent…', respond: 'Sending response…', configureHarness: 'Updating harness settings…', loadEarlier: 'Loading earlier messages…', loadSessions: 'Loading more chats…', refresh: 'Retrying…' };
|
|
912
990
|
return labels[operation] ?? `${operation.replaceAll('_', ' ')}…`;
|
|
913
991
|
}
|
|
914
992
|
|
|
@@ -998,6 +1076,11 @@ export function parseSupercodeUiIntent(value) {
|
|
|
998
1076
|
? { action: 'draft', text: intent.text }
|
|
999
1077
|
: null;
|
|
1000
1078
|
}
|
|
1079
|
+
if (intent.action === 'steer') {
|
|
1080
|
+
return exact('text') && typeof intent.text === 'string' && intent.text.trim() && intent.text.length <= 50_000
|
|
1081
|
+
? { action: 'steer', text: intent.text }
|
|
1082
|
+
: null;
|
|
1083
|
+
}
|
|
1001
1084
|
if (intent.action === 'send' || intent.action === 'new') {
|
|
1002
1085
|
const allowed = intent.action === 'new'
|
|
1003
1086
|
? exact('harness', 'mode', 'text', 'context', 'images')
|