@volter-ai-dev/supercode-ui 0.1.55 → 0.1.57
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 +155 -112
- package/embed.mjs +155 -112
- package/messenger.mjs +155 -112
- package/package.json +1 -1
- package/react/components.mjs +155 -112
- package/react/messenger.mjs +155 -112
- package/react/sessions.mjs +3 -4
- package/react/subagents.mjs +66 -21
- package/sessions.mjs +3 -4
- package/styles.css +2 -2
- package/subagents.mjs +66 -21
package/react/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 "react";
|
|
2318
2318
|
|
|
2319
2319
|
// src/sessions.jsx
|
|
2320
2320
|
import { useEffect as useEffect6, useLayoutEffect as useLayoutEffect3, useRef as useRef5, useState as useState4 } from "react";
|
|
@@ -2366,11 +2366,10 @@ function SessionRow({ row, state, onOpen, onOpenSubagents, now = Date.now() }) {
|
|
|
2366
2366
|
state.attachError?.key === row.key ? /* @__PURE__ */ jsx8("em", { children: state.attachError.message }) : null
|
|
2367
2367
|
] })
|
|
2368
2368
|
] }),
|
|
2369
|
-
row.subagentCount ? /* @__PURE__ */ jsxs7("button", { className: "scui-session-agents", type: "button", "aria-label": `
|
|
2369
|
+
row.subagentCount ? /* @__PURE__ */ jsxs7("button", { className: "scui-session-agents", type: "button", "aria-label": `Open ${row.subagentCount} agent sessions in ${title}`, onClick: () => onOpenSubagents?.(row), children: [
|
|
2370
2370
|
/* @__PURE__ */ jsx8(UiIcon, { name: "agents", size: 14 }),
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
row.subagentCount === 1 ? "agent" : "agents"
|
|
2371
|
+
"Agents \xB7 ",
|
|
2372
|
+
row.subagentCount
|
|
2374
2373
|
] }) : null
|
|
2375
2374
|
] });
|
|
2376
2375
|
}
|
|
@@ -2448,11 +2447,51 @@ function SessionList({ state, adapter, onOpen, onOpenSubagents, onNew, onClose,
|
|
|
2448
2447
|
}
|
|
2449
2448
|
|
|
2450
2449
|
// src/subagents.jsx
|
|
2450
|
+
import { useEffect as useEffect7, useRef as useRef6, useState as useState5 } from "react";
|
|
2451
2451
|
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
if (
|
|
2452
|
+
var ACTIVE_ACTIVITY = /* @__PURE__ */ new Set(["working", "running", "recent"]);
|
|
2453
|
+
function activityLabel(activity, age) {
|
|
2454
|
+
if (activity === "needs-input") return "Needs input";
|
|
2455
|
+
if (activity === "failed") return "Failed";
|
|
2456
|
+
if (activity === "unseen") return "New update";
|
|
2457
|
+
if (activity === "working") return "Working";
|
|
2458
|
+
if (activity === "running") return "Running";
|
|
2459
|
+
if (activity === "recent") return "Recent";
|
|
2460
|
+
if (activity === "finished") return "Finished";
|
|
2461
|
+
return age;
|
|
2462
|
+
}
|
|
2463
|
+
function SubagentRow({ row, inspector, adapter }) {
|
|
2464
|
+
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: [
|
|
2465
|
+
/* @__PURE__ */ jsx9(HarnessLogo, { id: row.harness, activity: row.activity, size: 30 }),
|
|
2466
|
+
/* @__PURE__ */ jsxs8("span", { children: [
|
|
2467
|
+
/* @__PURE__ */ jsx9("strong", { children: sessionDisplayName(row) }),
|
|
2468
|
+
/* @__PURE__ */ jsx9("small", { children: row.preview || (row.activity === "working" ? "Working\u2026" : row.cwd) })
|
|
2469
|
+
] }),
|
|
2470
|
+
/* @__PURE__ */ jsxs8("span", { children: [
|
|
2471
|
+
/* @__PURE__ */ jsx9("small", { children: activityLabel(row.activity, row.age) }),
|
|
2472
|
+
/* @__PURE__ */ jsx9(UiIcon, { name: "chevron", size: 14 })
|
|
2473
|
+
] })
|
|
2474
|
+
] });
|
|
2475
|
+
}
|
|
2476
|
+
function SubagentSection({ label, rows, inspector, adapter }) {
|
|
2477
|
+
if (!rows.length) return null;
|
|
2478
|
+
return /* @__PURE__ */ jsxs8("section", { className: "scui-subagent-section", "aria-labelledby": `scui-subagents-${label.toLowerCase().replaceAll(" ", "-")}`, children: [
|
|
2479
|
+
/* @__PURE__ */ jsx9("h2", { id: `scui-subagents-${label.toLowerCase().replaceAll(" ", "-")}`, children: label }),
|
|
2480
|
+
rows.map((row) => /* @__PURE__ */ jsx9(SubagentRow, { row, inspector, adapter }, row.key))
|
|
2481
|
+
] });
|
|
2482
|
+
}
|
|
2483
|
+
function SubagentInspectorContent({ state, adapter, onClose, inspector }) {
|
|
2455
2484
|
const selected = inspector.items.find((row) => row.key === inspector.selectedKey) ?? null;
|
|
2485
|
+
const active = inspector.items.filter((row) => ACTIVE_ACTIVITY.has(row.activity));
|
|
2486
|
+
const history = inspector.items.filter((row) => !ACTIVE_ACTIVITY.has(row.activity));
|
|
2487
|
+
const [historyOpen, setHistoryOpen] = useState5(false);
|
|
2488
|
+
const backButton = useRef6(null);
|
|
2489
|
+
useEffect7(() => {
|
|
2490
|
+
if (inspector.status === "ready" && !active.length) setHistoryOpen(true);
|
|
2491
|
+
}, [inspector.parentKey, inspector.status]);
|
|
2492
|
+
useEffect7(() => {
|
|
2493
|
+
backButton.current?.focus({ preventScroll: true });
|
|
2494
|
+
}, [selected?.key]);
|
|
2456
2495
|
const detailState = selected ? {
|
|
2457
2496
|
...state,
|
|
2458
2497
|
transcript: inspector.transcript,
|
|
@@ -2473,15 +2512,14 @@ function SubagentInspector({ state, adapter, onClose }) {
|
|
|
2473
2512
|
onClose();
|
|
2474
2513
|
};
|
|
2475
2514
|
const back = () => selected ? adapter.onIntent({ action: "openSubagents", key: inspector.parentKey }) : leave();
|
|
2476
|
-
return /* @__PURE__ */ jsxs8("section", { className: "scui-subagents", "aria-label": `
|
|
2515
|
+
return /* @__PURE__ */ jsxs8("section", { className: "scui-subagents", "aria-label": `Agents for ${inspector.parentTitle}`, children: [
|
|
2477
2516
|
/* @__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 }),
|
|
2517
|
+
/* @__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 }) }),
|
|
2518
|
+
selected ? /* @__PURE__ */ jsx9(HarnessLogo, { id: selected.harness, activity: selected.activity, size: 24 }) : /* @__PURE__ */ jsx9(UiIcon, { name: "agents", size: 20 }),
|
|
2480
2519
|
/* @__PURE__ */ jsxs8("span", { className: "scui-head-copy", children: [
|
|
2481
|
-
/* @__PURE__ */ jsx9("strong", { children: selected ? sessionDisplayName(selected) :
|
|
2482
|
-
/* @__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 }) })
|
|
2520
|
+
/* @__PURE__ */ jsx9("strong", { children: selected ? sessionDisplayName(selected) : "Agents" }),
|
|
2521
|
+
/* @__PURE__ */ jsx9("small", { children: selected ? `${harnessDisplayName(selected.harness)} \xB7 Read-only` : `${inspector.items.length} ${inspector.items.length === 1 ? "session" : "sessions"} \xB7 ${inspector.parentTitle}` })
|
|
2522
|
+
] })
|
|
2485
2523
|
] }),
|
|
2486
2524
|
inspector.status === "loading" ? /* @__PURE__ */ jsxs8("div", { className: "scui-subagents-loading", role: "status", children: [
|
|
2487
2525
|
/* @__PURE__ */ jsx9("i", {}),
|
|
@@ -2491,24 +2529,28 @@ function SubagentInspector({ state, adapter, onClose }) {
|
|
|
2491
2529
|
] })
|
|
2492
2530
|
] }) : null,
|
|
2493
2531
|
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__ */ jsxs8("
|
|
2497
|
-
/* @__PURE__ */
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
/* @__PURE__ */ jsx9(
|
|
2503
|
-
] })
|
|
2504
|
-
] }
|
|
2532
|
+
!selected && inspector.status === "ready" && inspector.items.length ? /* @__PURE__ */ jsxs8("div", { className: "scui-subagent-rows", children: [
|
|
2533
|
+
/* @__PURE__ */ jsx9(SubagentSection, { label: "Active", rows: active, inspector, adapter }),
|
|
2534
|
+
history.length ? /* @__PURE__ */ jsxs8("details", { className: "scui-subagent-history", open: historyOpen, onToggle: (event) => setHistoryOpen(event.currentTarget.open), children: [
|
|
2535
|
+
/* @__PURE__ */ jsxs8("summary", { children: [
|
|
2536
|
+
/* @__PURE__ */ jsx9("span", { children: "History" }),
|
|
2537
|
+
/* @__PURE__ */ jsx9("small", { children: history.length }),
|
|
2538
|
+
/* @__PURE__ */ jsx9(UiIcon, { name: "chevron", size: 14 })
|
|
2539
|
+
] }),
|
|
2540
|
+
/* @__PURE__ */ jsx9("div", { children: history.map((row) => /* @__PURE__ */ jsx9(SubagentRow, { row, inspector, adapter }, row.key)) })
|
|
2541
|
+
] }) : null
|
|
2542
|
+
] }) : null,
|
|
2505
2543
|
!selected && inspector.status === "ready" && !inspector.items.length ? /* @__PURE__ */ jsx9("div", { className: "scui-empty", children: "No native child sessions were found." }) : null,
|
|
2506
2544
|
selected && inspector.status === "ready" && detailState ? /* @__PURE__ */ jsx9(Conversation, { state: detailState, adapter, memoryKey: `subagent:${selected.key}` }) : null
|
|
2507
2545
|
] });
|
|
2508
2546
|
}
|
|
2547
|
+
function SubagentInspector({ state, adapter, onClose }) {
|
|
2548
|
+
if (!state.subagentInspector) return null;
|
|
2549
|
+
return /* @__PURE__ */ jsx9(SubagentInspectorContent, { state, adapter, onClose, inspector: state.subagentInspector });
|
|
2550
|
+
}
|
|
2509
2551
|
|
|
2510
2552
|
// src/settings.jsx
|
|
2511
|
-
import { useEffect as
|
|
2553
|
+
import { useEffect as useEffect8, useId as useId2, useMemo as useMemo2, useRef as useRef7, useState as useState6 } from "react";
|
|
2512
2554
|
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2513
2555
|
function HarnessAdvisory({ state, onReview }) {
|
|
2514
2556
|
const advisory = state.interopSettings?.advisories[0];
|
|
@@ -2531,12 +2573,12 @@ function initialValues(report, recommendedChange) {
|
|
|
2531
2573
|
function HarnessSettingsPanel({ state, adapter, onClose, recommendedChange = null }) {
|
|
2532
2574
|
const report = state.interopSettings;
|
|
2533
2575
|
const titleId = useId2();
|
|
2534
|
-
const panel =
|
|
2576
|
+
const panel = useRef7(null);
|
|
2535
2577
|
const valuesKey = `${report?.revision ?? ""}:${recommendedChange?.key ?? ""}:${recommendedChange?.value ?? ""}`;
|
|
2536
2578
|
const defaults = useMemo2(() => report ? initialValues(report, recommendedChange) : {}, [valuesKey]);
|
|
2537
|
-
const [values, setValues] =
|
|
2538
|
-
|
|
2539
|
-
|
|
2579
|
+
const [values, setValues] = useState6(defaults);
|
|
2580
|
+
useEffect8(() => setValues(defaults), [defaults]);
|
|
2581
|
+
useEffect8(() => {
|
|
2540
2582
|
panel.current?.querySelector("select, button")?.focus({ preventScroll: true });
|
|
2541
2583
|
const dismiss = (event) => {
|
|
2542
2584
|
if (event.key === "Escape") {
|
|
@@ -2624,11 +2666,11 @@ function HarnessReadiness({ harnesses, adapter }) {
|
|
|
2624
2666
|
] });
|
|
2625
2667
|
}
|
|
2626
2668
|
function HarnessPicker({ harnesses, value, disabled = false, adapter, onChange, logo: Logo = HarnessLogo }) {
|
|
2627
|
-
const [open, setOpen] =
|
|
2669
|
+
const [open, setOpen] = useState6(false);
|
|
2628
2670
|
const menuId = useId2();
|
|
2629
|
-
const root =
|
|
2630
|
-
const trigger =
|
|
2631
|
-
const panel =
|
|
2671
|
+
const root = useRef7(null);
|
|
2672
|
+
const trigger = useRef7(null);
|
|
2673
|
+
const panel = useRef7(null);
|
|
2632
2674
|
const available = harnesses.filter((item) => item.startable);
|
|
2633
2675
|
const unavailable = harnesses.filter((item) => !item.startable);
|
|
2634
2676
|
const selected = available.find((item) => item.id === value) ?? available[0] ?? null;
|
|
@@ -2636,7 +2678,7 @@ function HarnessPicker({ harnesses, value, disabled = false, adapter, onChange,
|
|
|
2636
2678
|
setOpen(false);
|
|
2637
2679
|
trigger.current?.focus({ preventScroll: true });
|
|
2638
2680
|
};
|
|
2639
|
-
|
|
2681
|
+
useEffect8(() => {
|
|
2640
2682
|
if (!open) return;
|
|
2641
2683
|
panel.current?.querySelector('[aria-selected="true"], [role="option"]')?.focus({ preventScroll: true });
|
|
2642
2684
|
const dismiss = (event) => {
|
|
@@ -2698,7 +2740,7 @@ function HarnessPicker({ harnesses, value, disabled = false, adapter, onChange,
|
|
|
2698
2740
|
}
|
|
2699
2741
|
|
|
2700
2742
|
// src/messenger.jsx
|
|
2701
|
-
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2743
|
+
import { Fragment as Fragment5, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2702
2744
|
var pendingMessageMemory = /* @__PURE__ */ new Map();
|
|
2703
2745
|
var messengerViewMemory = /* @__PURE__ */ new Map();
|
|
2704
2746
|
var newChatMemory = /* @__PURE__ */ new Map();
|
|
@@ -2741,10 +2783,10 @@ function Receipt({ state, adapter }) {
|
|
|
2741
2783
|
return null;
|
|
2742
2784
|
}
|
|
2743
2785
|
function ConversationActions({ state, adapter, actionPending, onNew, onSettings }) {
|
|
2744
|
-
const [open, setOpen] =
|
|
2745
|
-
const root =
|
|
2746
|
-
const panel =
|
|
2747
|
-
const trigger =
|
|
2786
|
+
const [open, setOpen] = useState7(false);
|
|
2787
|
+
const root = useRef8(null);
|
|
2788
|
+
const panel = useRef8(null);
|
|
2789
|
+
const trigger = useRef8(null);
|
|
2748
2790
|
const menuId = useId3();
|
|
2749
2791
|
const targets = state.harnesses.filter((item) => item.startable);
|
|
2750
2792
|
const groups = [
|
|
@@ -2768,7 +2810,7 @@ function ConversationActions({ state, adapter, actionPending, onNew, onSettings
|
|
|
2768
2810
|
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
2811
|
}
|
|
2770
2812
|
].filter((group) => group.items.length);
|
|
2771
|
-
|
|
2813
|
+
useEffect9(() => {
|
|
2772
2814
|
if (!open) return;
|
|
2773
2815
|
panel.current?.querySelector("button:not(:disabled)")?.focus({ preventScroll: true });
|
|
2774
2816
|
const dismiss = (event) => {
|
|
@@ -2819,11 +2861,11 @@ function ConversationActions({ state, adapter, actionPending, onNew, onSettings
|
|
|
2819
2861
|
] });
|
|
2820
2862
|
}
|
|
2821
2863
|
function ChatHeader({ state, adapter, pendingStatus, actionPending, onBack, onNew, onClose, onSettings, headerActions: HeaderActions }) {
|
|
2822
|
-
const back =
|
|
2864
|
+
const back = useRef8(null);
|
|
2823
2865
|
const harness = state.attached?.harness ?? state.harness;
|
|
2824
2866
|
const title = state.attached ? sessionDisplayName(state.attached) : harnessDisplayName(harness) || "Agent chat";
|
|
2825
2867
|
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
|
-
|
|
2868
|
+
useEffect9(() => {
|
|
2827
2869
|
if (state.mode === "mirror" && !state.canSend) back.current?.focus({ preventScroll: true });
|
|
2828
2870
|
}, []);
|
|
2829
2871
|
return /* @__PURE__ */ jsxs10("header", { className: "scui-head scui-chat-head", children: [
|
|
@@ -2846,26 +2888,26 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
2846
2888
|
const Header = slots.header;
|
|
2847
2889
|
const HeaderActions = slots.headerActions;
|
|
2848
2890
|
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 =
|
|
2891
|
+
const [pending, setPendingState] = useState7(() => pendingMessageMemory.get(memoryKey) ?? null);
|
|
2892
|
+
const [pendingAction, setPendingAction] = useState7(null);
|
|
2893
|
+
const [restoreDraft, setRestoreDraft] = useState7(null);
|
|
2894
|
+
const [settings, setSettings] = useState7(null);
|
|
2895
|
+
const restoreSequence = useRef8(0);
|
|
2896
|
+
const actionSequence = useRef8(0);
|
|
2897
|
+
const lastNavigation = useRef8(null);
|
|
2898
|
+
const acknowledged = useRef8(/* @__PURE__ */ new Set());
|
|
2857
2899
|
const setPending = (update) => setPendingState((current) => {
|
|
2858
2900
|
const next = typeof update === "function" ? update(current) : update;
|
|
2859
2901
|
if (next) boundedSet(pendingMessageMemory, memoryKey, next);
|
|
2860
2902
|
else pendingMessageMemory.delete(memoryKey);
|
|
2861
2903
|
return next;
|
|
2862
2904
|
});
|
|
2863
|
-
|
|
2905
|
+
useEffect9(() => {
|
|
2864
2906
|
setPendingState(pendingMessageMemory.get(memoryKey) ?? null);
|
|
2865
2907
|
setPendingAction(null);
|
|
2866
2908
|
setRestoreDraft(null);
|
|
2867
2909
|
}, [memoryKey]);
|
|
2868
|
-
|
|
2910
|
+
useEffect9(() => {
|
|
2869
2911
|
if (!navigation || navigation.id === lastNavigation.current) return;
|
|
2870
2912
|
lastNavigation.current = navigation.id;
|
|
2871
2913
|
if (navigation.draft === void 0 && !navigation.context?.length && !navigation.images?.length) return;
|
|
@@ -2876,7 +2918,7 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
2876
2918
|
images: navigation.images
|
|
2877
2919
|
});
|
|
2878
2920
|
}, [navigation]);
|
|
2879
|
-
|
|
2921
|
+
useEffect9(() => {
|
|
2880
2922
|
if (!pending) return;
|
|
2881
2923
|
if (state.transcript.some((entry) => entry.role === "user" && entry.text.trim() === pending.text.trim() && !pending.baselineIds.includes(entry.id))) {
|
|
2882
2924
|
setPending(null);
|
|
@@ -2905,7 +2947,7 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
2905
2947
|
setRestoreDraft({ id: restoreSequence.current, text: pending.text, context: pending.context, images: pending.images });
|
|
2906
2948
|
setPending({ ...pending, status: "editing" });
|
|
2907
2949
|
};
|
|
2908
|
-
|
|
2950
|
+
useEffect9(() => {
|
|
2909
2951
|
const key = state.attached?.key;
|
|
2910
2952
|
if (!key || !state.attention.some((item) => item.key === key)) {
|
|
2911
2953
|
if (key) acknowledged.current.delete(key);
|
|
@@ -2940,7 +2982,7 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
2940
2982
|
return result;
|
|
2941
2983
|
}
|
|
2942
2984
|
}), [adapter, state.error]);
|
|
2943
|
-
|
|
2985
|
+
useEffect9(() => {
|
|
2944
2986
|
if (!pendingAction) return;
|
|
2945
2987
|
if (state.operation && !pendingAction.seenOperation) {
|
|
2946
2988
|
setPendingAction({ ...pendingAction, seenOperation: true });
|
|
@@ -2977,18 +3019,18 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
|
|
|
2977
3019
|
const startable = state.harnesses.filter((item) => item.startable);
|
|
2978
3020
|
const startableKey = startable.map((item) => `${item.id}:${item.launchModes?.join(",")}:${item.preferredLaunchMode ?? ""}`).join("\0");
|
|
2979
3021
|
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 =
|
|
3022
|
+
const [harness, setHarness] = useState7(remembered.harness);
|
|
3023
|
+
const [draft, setDraft] = useState7(remembered.draft);
|
|
3024
|
+
const [context, setContext] = useState7(remembered.context);
|
|
3025
|
+
const [images, setImages] = useState7(remembered.images ?? []);
|
|
3026
|
+
const [modes, setModes] = useState7(remembered.modes ?? {});
|
|
3027
|
+
const [starting, setStarting] = useState7(null);
|
|
3028
|
+
const [picking, setPicking] = useState7(false);
|
|
3029
|
+
const [dragging, setDragging] = useState7(false);
|
|
3030
|
+
const [pickerError, setPickerError] = useState7(null);
|
|
3031
|
+
const startSequence = useRef8(0);
|
|
3032
|
+
const lastComposerCommand = useRef8(null);
|
|
3033
|
+
const textarea = useRef8(null);
|
|
2992
3034
|
const selectedHarness = startable.find((item) => item.id === harness) ?? null;
|
|
2993
3035
|
const Picker = components.HarnessPicker ?? HarnessPicker;
|
|
2994
3036
|
const Readiness = components.HarnessReadiness ?? HarnessReadiness;
|
|
@@ -2999,13 +3041,13 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
|
|
|
2999
3041
|
const terminalAttachments = mode === "terminal" && (context.length > 0 || images.length > 0);
|
|
3000
3042
|
const remember = (overrides = {}) => boundedSet(newChatMemory, memoryKey, { harness, draft, context, images, modes, ...overrides });
|
|
3001
3043
|
useAutosizeTextarea(textarea, draft);
|
|
3002
|
-
|
|
3044
|
+
useEffect9(() => {
|
|
3003
3045
|
if (startable.some((item) => item.id === harness)) return;
|
|
3004
3046
|
const next = startable[0]?.id ?? "";
|
|
3005
3047
|
setHarness(next);
|
|
3006
3048
|
remember({ harness: next });
|
|
3007
3049
|
}, [harness, startableKey]);
|
|
3008
|
-
|
|
3050
|
+
useEffect9(() => {
|
|
3009
3051
|
if (!starting || starting.mode === "terminal") return;
|
|
3010
3052
|
const sessionChanged = (state.attached?.key ?? null) !== starting.attachedKey;
|
|
3011
3053
|
const beganWorking = !starting.busy && state.busy;
|
|
@@ -3013,13 +3055,13 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
|
|
|
3013
3055
|
newChatMemory.delete(memoryKey);
|
|
3014
3056
|
onStarted("headless");
|
|
3015
3057
|
}, [memoryKey, onStarted, starting, state.attached?.key, state.busy]);
|
|
3016
|
-
|
|
3058
|
+
useEffect9(() => {
|
|
3017
3059
|
if (starting && state.error !== starting.initialError && !state.busy && !state.operation) setStarting(null);
|
|
3018
3060
|
}, [starting, state.busy, state.error, state.operation]);
|
|
3019
|
-
|
|
3061
|
+
useEffect9(() => {
|
|
3020
3062
|
textarea.current?.focus({ preventScroll: true });
|
|
3021
3063
|
}, []);
|
|
3022
|
-
|
|
3064
|
+
useEffect9(() => {
|
|
3023
3065
|
if (!navigation) return;
|
|
3024
3066
|
const nextHarness = startable.some((item) => item.id === navigation.harness) ? navigation.harness : harness;
|
|
3025
3067
|
const nextDraft = typeof navigation.draft === "string" ? navigation.draft : draft;
|
|
@@ -3032,7 +3074,7 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
|
|
|
3032
3074
|
remember({ harness: nextHarness, draft: nextDraft, context: nextContext, images: nextImages });
|
|
3033
3075
|
textarea.current?.focus({ preventScroll: true });
|
|
3034
3076
|
}, [navigation?.id]);
|
|
3035
|
-
|
|
3077
|
+
useEffect9(() => {
|
|
3036
3078
|
if (!composerCommand || composerCommand.id === lastComposerCommand.current) return;
|
|
3037
3079
|
lastComposerCommand.current = composerCommand.id;
|
|
3038
3080
|
if (composerCommand.action === "attach") {
|
|
@@ -3209,19 +3251,19 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
3209
3251
|
const contextCandidates = useMemo3(() => normalizeAttachmentCandidates(candidatesInput), [candidatesInput]);
|
|
3210
3252
|
const copy = { ...DEFAULT_LABELS, ...labels };
|
|
3211
3253
|
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 =
|
|
3254
|
+
const [view, setViewState] = useState7(initialView ?? (state.attention.length ? "list" : messengerViewMemory.get(memoryKey) ?? (state.attached || state.transcript.length ? "chat" : "list")));
|
|
3255
|
+
const [opening, setOpening] = useState7(null);
|
|
3256
|
+
const [newNavigation, setNewNavigation] = useState7(null);
|
|
3257
|
+
const [chatNavigation, setChatNavigation] = useState7(null);
|
|
3258
|
+
const [listFocus, setListFocus] = useState7(null);
|
|
3259
|
+
const [inspecting, setInspecting] = useState7(null);
|
|
3260
|
+
const lastNavigation = useRef8(null);
|
|
3219
3261
|
const setView = (next) => {
|
|
3220
3262
|
boundedSet(messengerViewMemory, memoryKey, next);
|
|
3221
3263
|
setViewState(next);
|
|
3222
3264
|
onViewChange?.(next);
|
|
3223
3265
|
};
|
|
3224
|
-
|
|
3266
|
+
useEffect9(() => {
|
|
3225
3267
|
if (!navigation || navigation.id === lastNavigation.current) return;
|
|
3226
3268
|
lastNavigation.current = navigation.id;
|
|
3227
3269
|
if (navigation.view === "list") {
|
|
@@ -3251,7 +3293,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
3251
3293
|
adapter.onIntent({ action: "attach", key: navigation.sessionKey });
|
|
3252
3294
|
}
|
|
3253
3295
|
}, [adapter, navigation, state.attached?.key, state.sessions]);
|
|
3254
|
-
|
|
3296
|
+
useEffect9(() => {
|
|
3255
3297
|
if (!opening) return;
|
|
3256
3298
|
if (state.attached?.key === opening.key) {
|
|
3257
3299
|
setOpening(null);
|
|
@@ -3279,35 +3321,36 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
3279
3321
|
...state,
|
|
3280
3322
|
subagentInspector: state.subagentInspector?.parentKey === inspectorParent.key ? state.subagentInspector : { parentKey: inspectorParent.key, parentTitle: sessionDisplayName(inspectorParent), status: "loading", items: [], selectedKey: null, transcript: [], error: null }
|
|
3281
3323
|
} : 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
|
-
|
|
3324
|
+
return /* @__PURE__ */ jsxs10("main", { className: `scui-root ${className}`, "data-view": inspectorState ? "agents" : view, "data-mode": state.mode, "aria-label": "Supercode messenger", children: [
|
|
3325
|
+
inspectorState ? /* @__PURE__ */ jsx11(SubagentInspector, { state: inspectorState, adapter, onClose: () => setInspecting(null) }) : /* @__PURE__ */ jsxs10(Fragment5, { children: [
|
|
3326
|
+
view === "list" ? /* @__PURE__ */ jsx11(SessionList, { state, adapter, focusKey: listFocus, onOpen: open, onOpenSubagents: openSubagents, onNew: () => {
|
|
3327
|
+
setListFocus("@new");
|
|
3328
|
+
setChatNavigation(null);
|
|
3329
|
+
setNewNavigation(null);
|
|
3330
|
+
setView("new");
|
|
3331
|
+
}, onClose: adapter.onClose ? close : void 0, components, labels: copy, memoryKey, slots, headerActions: HeaderActions }) : null,
|
|
3332
|
+
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,
|
|
3333
|
+
view === "chat" ? /* @__PURE__ */ jsx11(Chat, { state, adapter, onBack: () => {
|
|
3334
|
+
setListFocus(state.attached?.key ?? listFocus);
|
|
3335
|
+
setView("list");
|
|
3336
|
+
}, onNew: () => {
|
|
3337
|
+
setListFocus("@new");
|
|
3338
|
+
setChatNavigation(null);
|
|
3339
|
+
setNewNavigation(null);
|
|
3340
|
+
setView("new");
|
|
3341
|
+
}, onClose: adapter.onClose ? close : void 0, components, slots, labels: copy, contextCandidates, navigation: chatNavigation?.sessionKey === state.attached?.key ? chatNavigation : null, composerCommand }) : null,
|
|
3342
|
+
opening ? /* @__PURE__ */ jsxs10("div", { className: "scui-opening", role: "status", "aria-busy": "true", children: [
|
|
3343
|
+
/* @__PURE__ */ jsx11(HarnessLogo, { id: opening.harness, size: 34 }),
|
|
3344
|
+
/* @__PURE__ */ jsxs10("span", { children: [
|
|
3345
|
+
/* @__PURE__ */ jsxs10("strong", { children: [
|
|
3346
|
+
"Opening ",
|
|
3347
|
+
sessionDisplayName(opening)
|
|
3348
|
+
] }),
|
|
3349
|
+
/* @__PURE__ */ jsx11("small", { children: "Loading the latest transcript window\u2026" })
|
|
3305
3350
|
] }),
|
|
3306
|
-
/* @__PURE__ */ jsx11("
|
|
3307
|
-
] })
|
|
3308
|
-
|
|
3309
|
-
] }) : null,
|
|
3310
|
-
inspectorState ? /* @__PURE__ */ jsx11(SubagentInspector, { state: inspectorState, adapter, onClose: () => setInspecting(null) }) : null,
|
|
3351
|
+
/* @__PURE__ */ jsx11("i", {})
|
|
3352
|
+
] }) : null
|
|
3353
|
+
] }),
|
|
3311
3354
|
Footer ? /* @__PURE__ */ jsx11(Footer, { state, adapter, value: copy }) : null
|
|
3312
3355
|
] });
|
|
3313
3356
|
}
|