@volter-ai-dev/supercode-ui 0.1.55 → 0.1.56
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/components.mjs +153 -106
- package/embed.mjs +153 -106
- package/messenger.mjs +153 -106
- package/package.json +1 -1
- package/react/components.mjs +153 -106
- package/react/messenger.mjs +153 -106
- package/react/subagents.mjs +67 -19
- package/styles.css +2 -2
- package/subagents.mjs +67 -19
package/components.mjs
CHANGED
|
@@ -2314,7 +2314,7 @@ function Conversation({ state, adapter, components = {}, slots = {}, memoryKey =
|
|
|
2314
2314
|
}
|
|
2315
2315
|
|
|
2316
2316
|
// src/messenger.jsx
|
|
2317
|
-
import { useEffect as
|
|
2317
|
+
import { useEffect as useEffect9, useId as useId3, useMemo as useMemo3, useRef as useRef8, useState as useState7 } from "preact/hooks";
|
|
2318
2318
|
|
|
2319
2319
|
// src/sessions.jsx
|
|
2320
2320
|
import { useEffect as useEffect6, useLayoutEffect as useLayoutEffect3, useRef as useRef5, useState as useState4 } from "preact/hooks";
|
|
@@ -2448,11 +2448,53 @@ function SessionList({ state, adapter, onOpen, onOpenSubagents, onNew, onClose,
|
|
|
2448
2448
|
}
|
|
2449
2449
|
|
|
2450
2450
|
// src/subagents.jsx
|
|
2451
|
+
import { useEffect as useEffect7, useRef as useRef6, useState as useState5 } from "preact/hooks";
|
|
2451
2452
|
import { jsx as jsx9, jsxs as jsxs8 } from "preact/jsx-runtime";
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2453
|
+
var ATTENTION_ACTIVITY = /* @__PURE__ */ new Set(["needs-input", "failed", "unseen"]);
|
|
2454
|
+
var ACTIVE_ACTIVITY = /* @__PURE__ */ new Set(["working", "running", "recent"]);
|
|
2455
|
+
function activityLabel(activity, age) {
|
|
2456
|
+
if (activity === "needs-input") return "Needs input";
|
|
2457
|
+
if (activity === "failed") return "Failed";
|
|
2458
|
+
if (activity === "unseen") return "New update";
|
|
2459
|
+
if (activity === "working") return "Working";
|
|
2460
|
+
if (activity === "running") return "Running";
|
|
2461
|
+
if (activity === "recent") return "Recent";
|
|
2462
|
+
if (activity === "finished") return "Finished";
|
|
2463
|
+
return age;
|
|
2464
|
+
}
|
|
2465
|
+
function SubagentRow({ row, inspector, adapter }) {
|
|
2466
|
+
return /* @__PURE__ */ jsxs8("button", { className: "scui-subagent-row", type: "button", "data-activity": row.activity ?? "idle", onClick: () => adapter.onIntent({ action: "openSubagent", parentKey: inspector.parentKey, key: row.key }), children: [
|
|
2467
|
+
/* @__PURE__ */ jsx9(HarnessLogo, { id: row.harness, activity: row.activity, size: 30 }),
|
|
2468
|
+
/* @__PURE__ */ jsxs8("span", { children: [
|
|
2469
|
+
/* @__PURE__ */ jsx9("strong", { children: sessionDisplayName(row) }),
|
|
2470
|
+
/* @__PURE__ */ jsx9("small", { children: row.preview || (row.activity === "working" ? "Working\u2026" : row.cwd) })
|
|
2471
|
+
] }),
|
|
2472
|
+
/* @__PURE__ */ jsxs8("span", { children: [
|
|
2473
|
+
/* @__PURE__ */ jsx9("small", { children: activityLabel(row.activity, row.age) }),
|
|
2474
|
+
/* @__PURE__ */ jsx9(UiIcon, { name: "chevron", size: 14 })
|
|
2475
|
+
] })
|
|
2476
|
+
] });
|
|
2477
|
+
}
|
|
2478
|
+
function SubagentSection({ label, rows, inspector, adapter }) {
|
|
2479
|
+
if (!rows.length) return null;
|
|
2480
|
+
return /* @__PURE__ */ jsxs8("section", { className: "scui-subagent-section", "aria-labelledby": `scui-subagents-${label.toLowerCase().replaceAll(" ", "-")}`, children: [
|
|
2481
|
+
/* @__PURE__ */ jsx9("h2", { id: `scui-subagents-${label.toLowerCase().replaceAll(" ", "-")}`, children: label }),
|
|
2482
|
+
rows.map((row) => /* @__PURE__ */ jsx9(SubagentRow, { row, inspector, adapter }, row.key))
|
|
2483
|
+
] });
|
|
2484
|
+
}
|
|
2485
|
+
function SubagentInspectorContent({ state, adapter, onClose, inspector }) {
|
|
2455
2486
|
const selected = inspector.items.find((row) => row.key === inspector.selectedKey) ?? null;
|
|
2487
|
+
const attention = inspector.items.filter((row) => ATTENTION_ACTIVITY.has(row.activity));
|
|
2488
|
+
const active = inspector.items.filter((row) => ACTIVE_ACTIVITY.has(row.activity));
|
|
2489
|
+
const finished = inspector.items.filter((row) => !ATTENTION_ACTIVITY.has(row.activity) && !ACTIVE_ACTIVITY.has(row.activity));
|
|
2490
|
+
const [finishedOpen, setFinishedOpen] = useState5(false);
|
|
2491
|
+
const backButton = useRef6(null);
|
|
2492
|
+
useEffect7(() => {
|
|
2493
|
+
if (inspector.status === "ready" && !attention.length && !active.length) setFinishedOpen(true);
|
|
2494
|
+
}, [inspector.parentKey, inspector.status]);
|
|
2495
|
+
useEffect7(() => {
|
|
2496
|
+
backButton.current?.focus({ preventScroll: true });
|
|
2497
|
+
}, [selected?.key]);
|
|
2456
2498
|
const detailState = selected ? {
|
|
2457
2499
|
...state,
|
|
2458
2500
|
transcript: inspector.transcript,
|
|
@@ -2473,15 +2515,14 @@ function SubagentInspector({ state, adapter, onClose }) {
|
|
|
2473
2515
|
onClose();
|
|
2474
2516
|
};
|
|
2475
2517
|
const back = () => selected ? adapter.onIntent({ action: "openSubagents", key: inspector.parentKey }) : leave();
|
|
2476
|
-
return /* @__PURE__ */ jsxs8("section", { className: "scui-subagents", "aria-label": `
|
|
2518
|
+
return /* @__PURE__ */ jsxs8("section", { className: "scui-subagents", "aria-label": `Agents for ${inspector.parentTitle}`, children: [
|
|
2477
2519
|
/* @__PURE__ */ jsxs8("header", { className: "scui-head", children: [
|
|
2478
|
-
/* @__PURE__ */ jsx9("button", { type: "button", "aria-label": selected ? "Back to
|
|
2479
|
-
/* @__PURE__ */ jsx9(UiIcon, { name: "agents", size: 20 }),
|
|
2520
|
+
/* @__PURE__ */ jsx9("button", { ref: backButton, type: "button", "aria-label": selected ? "Back to agents" : "Back to chats", onClick: back, children: /* @__PURE__ */ jsx9(UiIcon, { name: "back", size: 17 }) }),
|
|
2521
|
+
selected ? /* @__PURE__ */ jsx9(HarnessLogo, { id: selected.harness, activity: selected.activity, size: 24 }) : /* @__PURE__ */ jsx9(UiIcon, { name: "agents", size: 20 }),
|
|
2480
2522
|
/* @__PURE__ */ jsxs8("span", { className: "scui-head-copy", children: [
|
|
2481
2523
|
/* @__PURE__ */ jsx9("strong", { children: selected ? sessionDisplayName(selected) : `${inspector.items.length || ""} ${inspector.items.length === 1 ? "agent" : "agents"}`.trim() }),
|
|
2482
2524
|
/* @__PURE__ */ jsx9("small", { children: selected ? `${harnessDisplayName(selected.harness)} \xB7 Read-only` : inspector.parentTitle })
|
|
2483
|
-
] })
|
|
2484
|
-
/* @__PURE__ */ jsx9("button", { type: "button", "aria-label": "Close subagent inspector", onClick: leave, children: /* @__PURE__ */ jsx9(UiIcon, { name: "close", size: 18 }) })
|
|
2525
|
+
] })
|
|
2485
2526
|
] }),
|
|
2486
2527
|
inspector.status === "loading" ? /* @__PURE__ */ jsxs8("div", { className: "scui-subagents-loading", role: "status", children: [
|
|
2487
2528
|
/* @__PURE__ */ jsx9("i", {}),
|
|
@@ -2491,24 +2532,29 @@ function SubagentInspector({ state, adapter, onClose }) {
|
|
|
2491
2532
|
] })
|
|
2492
2533
|
] }) : null,
|
|
2493
2534
|
inspector.error ? /* @__PURE__ */ jsx9("div", { className: "scui-error", role: "alert", children: inspector.error }) : null,
|
|
2494
|
-
!selected && inspector.status === "ready" ? /* @__PURE__ */
|
|
2495
|
-
/* @__PURE__ */ jsx9(
|
|
2496
|
-
/* @__PURE__ */
|
|
2497
|
-
|
|
2498
|
-
/* @__PURE__ */
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2535
|
+
!selected && inspector.status === "ready" && inspector.items.length ? /* @__PURE__ */ jsxs8("div", { className: "scui-subagent-rows", children: [
|
|
2536
|
+
/* @__PURE__ */ jsx9(SubagentSection, { label: "Needs attention", rows: attention, inspector, adapter }),
|
|
2537
|
+
/* @__PURE__ */ jsx9(SubagentSection, { label: "Active", rows: active, inspector, adapter }),
|
|
2538
|
+
finished.length ? /* @__PURE__ */ jsxs8("details", { className: "scui-subagent-history", open: finishedOpen, onToggle: (event) => setFinishedOpen(event.currentTarget.open), children: [
|
|
2539
|
+
/* @__PURE__ */ jsxs8("summary", { children: [
|
|
2540
|
+
/* @__PURE__ */ jsx9("span", { children: "Finished" }),
|
|
2541
|
+
/* @__PURE__ */ jsx9("small", { children: finished.length }),
|
|
2542
|
+
/* @__PURE__ */ jsx9(UiIcon, { name: "chevron", size: 14 })
|
|
2543
|
+
] }),
|
|
2544
|
+
/* @__PURE__ */ jsx9("div", { children: finished.map((row) => /* @__PURE__ */ jsx9(SubagentRow, { row, inspector, adapter }, row.key)) })
|
|
2545
|
+
] }) : null
|
|
2546
|
+
] }) : null,
|
|
2505
2547
|
!selected && inspector.status === "ready" && !inspector.items.length ? /* @__PURE__ */ jsx9("div", { className: "scui-empty", children: "No native child sessions were found." }) : null,
|
|
2506
2548
|
selected && inspector.status === "ready" && detailState ? /* @__PURE__ */ jsx9(Conversation, { state: detailState, adapter, memoryKey: `subagent:${selected.key}` }) : null
|
|
2507
2549
|
] });
|
|
2508
2550
|
}
|
|
2551
|
+
function SubagentInspector({ state, adapter, onClose }) {
|
|
2552
|
+
if (!state.subagentInspector) return null;
|
|
2553
|
+
return /* @__PURE__ */ jsx9(SubagentInspectorContent, { state, adapter, onClose, inspector: state.subagentInspector });
|
|
2554
|
+
}
|
|
2509
2555
|
|
|
2510
2556
|
// src/settings.jsx
|
|
2511
|
-
import { useEffect as
|
|
2557
|
+
import { useEffect as useEffect8, useId as useId2, useMemo as useMemo2, useRef as useRef7, useState as useState6 } from "preact/hooks";
|
|
2512
2558
|
import { jsx as jsx10, jsxs as jsxs9 } from "preact/jsx-runtime";
|
|
2513
2559
|
function HarnessAdvisory({ state, onReview }) {
|
|
2514
2560
|
const advisory = state.interopSettings?.advisories[0];
|
|
@@ -2531,12 +2577,12 @@ function initialValues(report, recommendedChange) {
|
|
|
2531
2577
|
function HarnessSettingsPanel({ state, adapter, onClose, recommendedChange = null }) {
|
|
2532
2578
|
const report = state.interopSettings;
|
|
2533
2579
|
const titleId = useId2();
|
|
2534
|
-
const panel =
|
|
2580
|
+
const panel = useRef7(null);
|
|
2535
2581
|
const valuesKey = `${report?.revision ?? ""}:${recommendedChange?.key ?? ""}:${recommendedChange?.value ?? ""}`;
|
|
2536
2582
|
const defaults = useMemo2(() => report ? initialValues(report, recommendedChange) : {}, [valuesKey]);
|
|
2537
|
-
const [values, setValues] =
|
|
2538
|
-
|
|
2539
|
-
|
|
2583
|
+
const [values, setValues] = useState6(defaults);
|
|
2584
|
+
useEffect8(() => setValues(defaults), [defaults]);
|
|
2585
|
+
useEffect8(() => {
|
|
2540
2586
|
panel.current?.querySelector("select, button")?.focus({ preventScroll: true });
|
|
2541
2587
|
const dismiss = (event) => {
|
|
2542
2588
|
if (event.key === "Escape") {
|
|
@@ -2624,11 +2670,11 @@ function HarnessReadiness({ harnesses, adapter }) {
|
|
|
2624
2670
|
] });
|
|
2625
2671
|
}
|
|
2626
2672
|
function HarnessPicker({ harnesses, value, disabled = false, adapter, onChange, logo: Logo = HarnessLogo }) {
|
|
2627
|
-
const [open, setOpen] =
|
|
2673
|
+
const [open, setOpen] = useState6(false);
|
|
2628
2674
|
const menuId = useId2();
|
|
2629
|
-
const root =
|
|
2630
|
-
const trigger =
|
|
2631
|
-
const panel =
|
|
2675
|
+
const root = useRef7(null);
|
|
2676
|
+
const trigger = useRef7(null);
|
|
2677
|
+
const panel = useRef7(null);
|
|
2632
2678
|
const available = harnesses.filter((item) => item.startable);
|
|
2633
2679
|
const unavailable = harnesses.filter((item) => !item.startable);
|
|
2634
2680
|
const selected = available.find((item) => item.id === value) ?? available[0] ?? null;
|
|
@@ -2636,7 +2682,7 @@ function HarnessPicker({ harnesses, value, disabled = false, adapter, onChange,
|
|
|
2636
2682
|
setOpen(false);
|
|
2637
2683
|
trigger.current?.focus({ preventScroll: true });
|
|
2638
2684
|
};
|
|
2639
|
-
|
|
2685
|
+
useEffect8(() => {
|
|
2640
2686
|
if (!open) return;
|
|
2641
2687
|
panel.current?.querySelector('[aria-selected="true"], [role="option"]')?.focus({ preventScroll: true });
|
|
2642
2688
|
const dismiss = (event) => {
|
|
@@ -2698,7 +2744,7 @@ function HarnessPicker({ harnesses, value, disabled = false, adapter, onChange,
|
|
|
2698
2744
|
}
|
|
2699
2745
|
|
|
2700
2746
|
// src/messenger.jsx
|
|
2701
|
-
import { jsx as jsx11, jsxs as jsxs10 } from "preact/jsx-runtime";
|
|
2747
|
+
import { Fragment as Fragment5, jsx as jsx11, jsxs as jsxs10 } from "preact/jsx-runtime";
|
|
2702
2748
|
var pendingMessageMemory = /* @__PURE__ */ new Map();
|
|
2703
2749
|
var messengerViewMemory = /* @__PURE__ */ new Map();
|
|
2704
2750
|
var newChatMemory = /* @__PURE__ */ new Map();
|
|
@@ -2741,10 +2787,10 @@ function Receipt({ state, adapter }) {
|
|
|
2741
2787
|
return null;
|
|
2742
2788
|
}
|
|
2743
2789
|
function ConversationActions({ state, adapter, actionPending, onNew, onSettings }) {
|
|
2744
|
-
const [open, setOpen] =
|
|
2745
|
-
const root =
|
|
2746
|
-
const panel =
|
|
2747
|
-
const trigger =
|
|
2790
|
+
const [open, setOpen] = useState7(false);
|
|
2791
|
+
const root = useRef8(null);
|
|
2792
|
+
const panel = useRef8(null);
|
|
2793
|
+
const trigger = useRef8(null);
|
|
2748
2794
|
const menuId = useId3();
|
|
2749
2795
|
const targets = state.harnesses.filter((item) => item.startable);
|
|
2750
2796
|
const groups = [
|
|
@@ -2768,7 +2814,7 @@ function ConversationActions({ state, adapter, actionPending, onNew, onSettings
|
|
|
2768
2814
|
items: state.canBranch ? targets.map((target) => ({ key: `branch:${target.id}`, label: target.id === state.harness ? `Fork in ${target.label}` : `Continue with ${target.label}`, intent: { action: "branch", targetHarness: target.id } })) : []
|
|
2769
2815
|
}
|
|
2770
2816
|
].filter((group) => group.items.length);
|
|
2771
|
-
|
|
2817
|
+
useEffect9(() => {
|
|
2772
2818
|
if (!open) return;
|
|
2773
2819
|
panel.current?.querySelector("button:not(:disabled)")?.focus({ preventScroll: true });
|
|
2774
2820
|
const dismiss = (event) => {
|
|
@@ -2819,11 +2865,11 @@ function ConversationActions({ state, adapter, actionPending, onNew, onSettings
|
|
|
2819
2865
|
] });
|
|
2820
2866
|
}
|
|
2821
2867
|
function ChatHeader({ state, adapter, pendingStatus, actionPending, onBack, onNew, onClose, onSettings, headerActions: HeaderActions }) {
|
|
2822
|
-
const back =
|
|
2868
|
+
const back = useRef8(null);
|
|
2823
2869
|
const harness = state.attached?.harness ?? state.harness;
|
|
2824
2870
|
const title = state.attached ? sessionDisplayName(state.attached) : harnessDisplayName(harness) || "Agent chat";
|
|
2825
2871
|
const status = state.needsInput ? "Needs input" : pendingStatus === "failed" ? "Send failed" : state.busy ? "Working" : pendingStatus === "sending" ? "Sending" : pendingStatus === "editing" ? "Editing message" : state.messaging === "live_peer" ? "Live" : state.mode === "mirror" ? "Read-only" : "Ready";
|
|
2826
|
-
|
|
2872
|
+
useEffect9(() => {
|
|
2827
2873
|
if (state.mode === "mirror" && !state.canSend) back.current?.focus({ preventScroll: true });
|
|
2828
2874
|
}, []);
|
|
2829
2875
|
return /* @__PURE__ */ jsxs10("header", { className: "scui-head scui-chat-head", children: [
|
|
@@ -2846,26 +2892,26 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
2846
2892
|
const Header = slots.header;
|
|
2847
2893
|
const HeaderActions = slots.headerActions;
|
|
2848
2894
|
const memoryKey = state.attached?.key || `${state.harness}:${state.workspace}`;
|
|
2849
|
-
const [pending, setPendingState] =
|
|
2850
|
-
const [pendingAction, setPendingAction] =
|
|
2851
|
-
const [restoreDraft, setRestoreDraft] =
|
|
2852
|
-
const [settings, setSettings] =
|
|
2853
|
-
const restoreSequence =
|
|
2854
|
-
const actionSequence =
|
|
2855
|
-
const lastNavigation =
|
|
2856
|
-
const acknowledged =
|
|
2895
|
+
const [pending, setPendingState] = useState7(() => pendingMessageMemory.get(memoryKey) ?? null);
|
|
2896
|
+
const [pendingAction, setPendingAction] = useState7(null);
|
|
2897
|
+
const [restoreDraft, setRestoreDraft] = useState7(null);
|
|
2898
|
+
const [settings, setSettings] = useState7(null);
|
|
2899
|
+
const restoreSequence = useRef8(0);
|
|
2900
|
+
const actionSequence = useRef8(0);
|
|
2901
|
+
const lastNavigation = useRef8(null);
|
|
2902
|
+
const acknowledged = useRef8(/* @__PURE__ */ new Set());
|
|
2857
2903
|
const setPending = (update) => setPendingState((current) => {
|
|
2858
2904
|
const next = typeof update === "function" ? update(current) : update;
|
|
2859
2905
|
if (next) boundedSet(pendingMessageMemory, memoryKey, next);
|
|
2860
2906
|
else pendingMessageMemory.delete(memoryKey);
|
|
2861
2907
|
return next;
|
|
2862
2908
|
});
|
|
2863
|
-
|
|
2909
|
+
useEffect9(() => {
|
|
2864
2910
|
setPendingState(pendingMessageMemory.get(memoryKey) ?? null);
|
|
2865
2911
|
setPendingAction(null);
|
|
2866
2912
|
setRestoreDraft(null);
|
|
2867
2913
|
}, [memoryKey]);
|
|
2868
|
-
|
|
2914
|
+
useEffect9(() => {
|
|
2869
2915
|
if (!navigation || navigation.id === lastNavigation.current) return;
|
|
2870
2916
|
lastNavigation.current = navigation.id;
|
|
2871
2917
|
if (navigation.draft === void 0 && !navigation.context?.length && !navigation.images?.length) return;
|
|
@@ -2876,7 +2922,7 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
2876
2922
|
images: navigation.images
|
|
2877
2923
|
});
|
|
2878
2924
|
}, [navigation]);
|
|
2879
|
-
|
|
2925
|
+
useEffect9(() => {
|
|
2880
2926
|
if (!pending) return;
|
|
2881
2927
|
if (state.transcript.some((entry) => entry.role === "user" && entry.text.trim() === pending.text.trim() && !pending.baselineIds.includes(entry.id))) {
|
|
2882
2928
|
setPending(null);
|
|
@@ -2905,7 +2951,7 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
2905
2951
|
setRestoreDraft({ id: restoreSequence.current, text: pending.text, context: pending.context, images: pending.images });
|
|
2906
2952
|
setPending({ ...pending, status: "editing" });
|
|
2907
2953
|
};
|
|
2908
|
-
|
|
2954
|
+
useEffect9(() => {
|
|
2909
2955
|
const key = state.attached?.key;
|
|
2910
2956
|
if (!key || !state.attention.some((item) => item.key === key)) {
|
|
2911
2957
|
if (key) acknowledged.current.delete(key);
|
|
@@ -2940,7 +2986,7 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
2940
2986
|
return result;
|
|
2941
2987
|
}
|
|
2942
2988
|
}), [adapter, state.error]);
|
|
2943
|
-
|
|
2989
|
+
useEffect9(() => {
|
|
2944
2990
|
if (!pendingAction) return;
|
|
2945
2991
|
if (state.operation && !pendingAction.seenOperation) {
|
|
2946
2992
|
setPendingAction({ ...pendingAction, seenOperation: true });
|
|
@@ -2977,18 +3023,18 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
|
|
|
2977
3023
|
const startable = state.harnesses.filter((item) => item.startable);
|
|
2978
3024
|
const startableKey = startable.map((item) => `${item.id}:${item.launchModes?.join(",")}:${item.preferredLaunchMode ?? ""}`).join("\0");
|
|
2979
3025
|
const remembered = newChatMemory.get(memoryKey) ?? { harness: startable[0]?.id ?? "", draft: "", context: [], images: [], modes: {} };
|
|
2980
|
-
const [harness, setHarness] =
|
|
2981
|
-
const [draft, setDraft] =
|
|
2982
|
-
const [context, setContext] =
|
|
2983
|
-
const [images, setImages] =
|
|
2984
|
-
const [modes, setModes] =
|
|
2985
|
-
const [starting, setStarting] =
|
|
2986
|
-
const [picking, setPicking] =
|
|
2987
|
-
const [dragging, setDragging] =
|
|
2988
|
-
const [pickerError, setPickerError] =
|
|
2989
|
-
const startSequence =
|
|
2990
|
-
const lastComposerCommand =
|
|
2991
|
-
const textarea =
|
|
3026
|
+
const [harness, setHarness] = useState7(remembered.harness);
|
|
3027
|
+
const [draft, setDraft] = useState7(remembered.draft);
|
|
3028
|
+
const [context, setContext] = useState7(remembered.context);
|
|
3029
|
+
const [images, setImages] = useState7(remembered.images ?? []);
|
|
3030
|
+
const [modes, setModes] = useState7(remembered.modes ?? {});
|
|
3031
|
+
const [starting, setStarting] = useState7(null);
|
|
3032
|
+
const [picking, setPicking] = useState7(false);
|
|
3033
|
+
const [dragging, setDragging] = useState7(false);
|
|
3034
|
+
const [pickerError, setPickerError] = useState7(null);
|
|
3035
|
+
const startSequence = useRef8(0);
|
|
3036
|
+
const lastComposerCommand = useRef8(null);
|
|
3037
|
+
const textarea = useRef8(null);
|
|
2992
3038
|
const selectedHarness = startable.find((item) => item.id === harness) ?? null;
|
|
2993
3039
|
const Picker = components.HarnessPicker ?? HarnessPicker;
|
|
2994
3040
|
const Readiness = components.HarnessReadiness ?? HarnessReadiness;
|
|
@@ -2999,13 +3045,13 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
|
|
|
2999
3045
|
const terminalAttachments = mode === "terminal" && (context.length > 0 || images.length > 0);
|
|
3000
3046
|
const remember = (overrides = {}) => boundedSet(newChatMemory, memoryKey, { harness, draft, context, images, modes, ...overrides });
|
|
3001
3047
|
useAutosizeTextarea(textarea, draft);
|
|
3002
|
-
|
|
3048
|
+
useEffect9(() => {
|
|
3003
3049
|
if (startable.some((item) => item.id === harness)) return;
|
|
3004
3050
|
const next = startable[0]?.id ?? "";
|
|
3005
3051
|
setHarness(next);
|
|
3006
3052
|
remember({ harness: next });
|
|
3007
3053
|
}, [harness, startableKey]);
|
|
3008
|
-
|
|
3054
|
+
useEffect9(() => {
|
|
3009
3055
|
if (!starting || starting.mode === "terminal") return;
|
|
3010
3056
|
const sessionChanged = (state.attached?.key ?? null) !== starting.attachedKey;
|
|
3011
3057
|
const beganWorking = !starting.busy && state.busy;
|
|
@@ -3013,13 +3059,13 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
|
|
|
3013
3059
|
newChatMemory.delete(memoryKey);
|
|
3014
3060
|
onStarted("headless");
|
|
3015
3061
|
}, [memoryKey, onStarted, starting, state.attached?.key, state.busy]);
|
|
3016
|
-
|
|
3062
|
+
useEffect9(() => {
|
|
3017
3063
|
if (starting && state.error !== starting.initialError && !state.busy && !state.operation) setStarting(null);
|
|
3018
3064
|
}, [starting, state.busy, state.error, state.operation]);
|
|
3019
|
-
|
|
3065
|
+
useEffect9(() => {
|
|
3020
3066
|
textarea.current?.focus({ preventScroll: true });
|
|
3021
3067
|
}, []);
|
|
3022
|
-
|
|
3068
|
+
useEffect9(() => {
|
|
3023
3069
|
if (!navigation) return;
|
|
3024
3070
|
const nextHarness = startable.some((item) => item.id === navigation.harness) ? navigation.harness : harness;
|
|
3025
3071
|
const nextDraft = typeof navigation.draft === "string" ? navigation.draft : draft;
|
|
@@ -3032,7 +3078,7 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
|
|
|
3032
3078
|
remember({ harness: nextHarness, draft: nextDraft, context: nextContext, images: nextImages });
|
|
3033
3079
|
textarea.current?.focus({ preventScroll: true });
|
|
3034
3080
|
}, [navigation?.id]);
|
|
3035
|
-
|
|
3081
|
+
useEffect9(() => {
|
|
3036
3082
|
if (!composerCommand || composerCommand.id === lastComposerCommand.current) return;
|
|
3037
3083
|
lastComposerCommand.current = composerCommand.id;
|
|
3038
3084
|
if (composerCommand.action === "attach") {
|
|
@@ -3209,19 +3255,19 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
3209
3255
|
const contextCandidates = useMemo3(() => normalizeAttachmentCandidates(candidatesInput), [candidatesInput]);
|
|
3210
3256
|
const copy = { ...DEFAULT_LABELS, ...labels };
|
|
3211
3257
|
const memoryKey = state.workspace || "@default";
|
|
3212
|
-
const [view, setViewState] =
|
|
3213
|
-
const [opening, setOpening] =
|
|
3214
|
-
const [newNavigation, setNewNavigation] =
|
|
3215
|
-
const [chatNavigation, setChatNavigation] =
|
|
3216
|
-
const [listFocus, setListFocus] =
|
|
3217
|
-
const [inspecting, setInspecting] =
|
|
3218
|
-
const lastNavigation =
|
|
3258
|
+
const [view, setViewState] = useState7(initialView ?? (state.attention.length ? "list" : messengerViewMemory.get(memoryKey) ?? (state.attached || state.transcript.length ? "chat" : "list")));
|
|
3259
|
+
const [opening, setOpening] = useState7(null);
|
|
3260
|
+
const [newNavigation, setNewNavigation] = useState7(null);
|
|
3261
|
+
const [chatNavigation, setChatNavigation] = useState7(null);
|
|
3262
|
+
const [listFocus, setListFocus] = useState7(null);
|
|
3263
|
+
const [inspecting, setInspecting] = useState7(null);
|
|
3264
|
+
const lastNavigation = useRef8(null);
|
|
3219
3265
|
const setView = (next) => {
|
|
3220
3266
|
boundedSet(messengerViewMemory, memoryKey, next);
|
|
3221
3267
|
setViewState(next);
|
|
3222
3268
|
onViewChange?.(next);
|
|
3223
3269
|
};
|
|
3224
|
-
|
|
3270
|
+
useEffect9(() => {
|
|
3225
3271
|
if (!navigation || navigation.id === lastNavigation.current) return;
|
|
3226
3272
|
lastNavigation.current = navigation.id;
|
|
3227
3273
|
if (navigation.view === "list") {
|
|
@@ -3251,7 +3297,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
3251
3297
|
adapter.onIntent({ action: "attach", key: navigation.sessionKey });
|
|
3252
3298
|
}
|
|
3253
3299
|
}, [adapter, navigation, state.attached?.key, state.sessions]);
|
|
3254
|
-
|
|
3300
|
+
useEffect9(() => {
|
|
3255
3301
|
if (!opening) return;
|
|
3256
3302
|
if (state.attached?.key === opening.key) {
|
|
3257
3303
|
setOpening(null);
|
|
@@ -3279,35 +3325,36 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
3279
3325
|
...state,
|
|
3280
3326
|
subagentInspector: state.subagentInspector?.parentKey === inspectorParent.key ? state.subagentInspector : { parentKey: inspectorParent.key, parentTitle: sessionDisplayName(inspectorParent), status: "loading", items: [], selectedKey: null, transcript: [], error: null }
|
|
3281
3327
|
} : null;
|
|
3282
|
-
return /* @__PURE__ */ jsxs10("main", { className: `scui-root ${className}`, "data-view": view, "data-mode": state.mode, "aria-label": "Supercode messenger", children: [
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
/* @__PURE__ */
|
|
3301
|
-
|
|
3302
|
-
/* @__PURE__ */ jsxs10("
|
|
3303
|
-
|
|
3304
|
-
|
|
3328
|
+
return /* @__PURE__ */ jsxs10("main", { className: `scui-root ${className}`, "data-view": inspectorState ? "agents" : view, "data-mode": state.mode, "aria-label": "Supercode messenger", children: [
|
|
3329
|
+
inspectorState ? /* @__PURE__ */ jsx11(SubagentInspector, { state: inspectorState, adapter, onClose: () => setInspecting(null) }) : /* @__PURE__ */ jsxs10(Fragment5, { children: [
|
|
3330
|
+
view === "list" ? /* @__PURE__ */ jsx11(SessionList, { state, adapter, focusKey: listFocus, onOpen: open, onOpenSubagents: openSubagents, onNew: () => {
|
|
3331
|
+
setListFocus("@new");
|
|
3332
|
+
setChatNavigation(null);
|
|
3333
|
+
setNewNavigation(null);
|
|
3334
|
+
setView("new");
|
|
3335
|
+
}, onClose: adapter.onClose ? close : void 0, components, labels: copy, memoryKey, slots, headerActions: HeaderActions }) : null,
|
|
3336
|
+
view === "new" ? /* @__PURE__ */ jsx11(NewChat, { state, adapter, onBack: () => setView("list"), onClose: adapter.onClose ? close : void 0, onStarted: (mode) => setView(mode === "terminal" ? "list" : "chat"), labels: copy, memoryKey, headerActions: HeaderActions, contextCandidates, components, navigation: newNavigation, composerCommand }) : null,
|
|
3337
|
+
view === "chat" ? /* @__PURE__ */ jsx11(Chat, { state, adapter, onBack: () => {
|
|
3338
|
+
setListFocus(state.attached?.key ?? listFocus);
|
|
3339
|
+
setView("list");
|
|
3340
|
+
}, onNew: () => {
|
|
3341
|
+
setListFocus("@new");
|
|
3342
|
+
setChatNavigation(null);
|
|
3343
|
+
setNewNavigation(null);
|
|
3344
|
+
setView("new");
|
|
3345
|
+
}, onClose: adapter.onClose ? close : void 0, components, slots, labels: copy, contextCandidates, navigation: chatNavigation?.sessionKey === state.attached?.key ? chatNavigation : null, composerCommand }) : null,
|
|
3346
|
+
opening ? /* @__PURE__ */ jsxs10("div", { className: "scui-opening", role: "status", "aria-busy": "true", children: [
|
|
3347
|
+
/* @__PURE__ */ jsx11(HarnessLogo, { id: opening.harness, size: 34 }),
|
|
3348
|
+
/* @__PURE__ */ jsxs10("span", { children: [
|
|
3349
|
+
/* @__PURE__ */ jsxs10("strong", { children: [
|
|
3350
|
+
"Opening ",
|
|
3351
|
+
sessionDisplayName(opening)
|
|
3352
|
+
] }),
|
|
3353
|
+
/* @__PURE__ */ jsx11("small", { children: "Loading the latest transcript window\u2026" })
|
|
3305
3354
|
] }),
|
|
3306
|
-
/* @__PURE__ */ jsx11("
|
|
3307
|
-
] })
|
|
3308
|
-
|
|
3309
|
-
] }) : null,
|
|
3310
|
-
inspectorState ? /* @__PURE__ */ jsx11(SubagentInspector, { state: inspectorState, adapter, onClose: () => setInspecting(null) }) : null,
|
|
3355
|
+
/* @__PURE__ */ jsx11("i", {})
|
|
3356
|
+
] }) : null
|
|
3357
|
+
] }),
|
|
3311
3358
|
Footer ? /* @__PURE__ */ jsx11(Footer, { state, adapter, value: copy }) : null
|
|
3312
3359
|
] });
|
|
3313
3360
|
}
|