@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/messenger.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/messenger.jsx
|
|
2
|
-
import { useEffect as
|
|
2
|
+
import { useEffect as useEffect9, useId as useId3, useMemo as useMemo3, useRef as useRef8, useState as useState7 } from "preact/hooks";
|
|
3
3
|
|
|
4
4
|
// core.mjs
|
|
5
5
|
var HARNESS_NAMES = Object.freeze({
|
|
@@ -2362,11 +2362,53 @@ function SessionList({ state, adapter, onOpen, onOpenSubagents, onNew, onClose,
|
|
|
2362
2362
|
}
|
|
2363
2363
|
|
|
2364
2364
|
// src/subagents.jsx
|
|
2365
|
+
import { useEffect as useEffect7, useRef as useRef6, useState as useState5 } from "preact/hooks";
|
|
2365
2366
|
import { jsx as jsx8, jsxs as jsxs7 } from "preact/jsx-runtime";
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2367
|
+
var ATTENTION_ACTIVITY = /* @__PURE__ */ new Set(["needs-input", "failed", "unseen"]);
|
|
2368
|
+
var ACTIVE_ACTIVITY = /* @__PURE__ */ new Set(["working", "running", "recent"]);
|
|
2369
|
+
function activityLabel(activity, age) {
|
|
2370
|
+
if (activity === "needs-input") return "Needs input";
|
|
2371
|
+
if (activity === "failed") return "Failed";
|
|
2372
|
+
if (activity === "unseen") return "New update";
|
|
2373
|
+
if (activity === "working") return "Working";
|
|
2374
|
+
if (activity === "running") return "Running";
|
|
2375
|
+
if (activity === "recent") return "Recent";
|
|
2376
|
+
if (activity === "finished") return "Finished";
|
|
2377
|
+
return age;
|
|
2378
|
+
}
|
|
2379
|
+
function SubagentRow({ row, inspector, adapter }) {
|
|
2380
|
+
return /* @__PURE__ */ jsxs7("button", { className: "scui-subagent-row", type: "button", "data-activity": row.activity ?? "idle", onClick: () => adapter.onIntent({ action: "openSubagent", parentKey: inspector.parentKey, key: row.key }), children: [
|
|
2381
|
+
/* @__PURE__ */ jsx8(HarnessLogo, { id: row.harness, activity: row.activity, size: 30 }),
|
|
2382
|
+
/* @__PURE__ */ jsxs7("span", { children: [
|
|
2383
|
+
/* @__PURE__ */ jsx8("strong", { children: sessionDisplayName(row) }),
|
|
2384
|
+
/* @__PURE__ */ jsx8("small", { children: row.preview || (row.activity === "working" ? "Working\u2026" : row.cwd) })
|
|
2385
|
+
] }),
|
|
2386
|
+
/* @__PURE__ */ jsxs7("span", { children: [
|
|
2387
|
+
/* @__PURE__ */ jsx8("small", { children: activityLabel(row.activity, row.age) }),
|
|
2388
|
+
/* @__PURE__ */ jsx8(UiIcon, { name: "chevron", size: 14 })
|
|
2389
|
+
] })
|
|
2390
|
+
] });
|
|
2391
|
+
}
|
|
2392
|
+
function SubagentSection({ label, rows, inspector, adapter }) {
|
|
2393
|
+
if (!rows.length) return null;
|
|
2394
|
+
return /* @__PURE__ */ jsxs7("section", { className: "scui-subagent-section", "aria-labelledby": `scui-subagents-${label.toLowerCase().replaceAll(" ", "-")}`, children: [
|
|
2395
|
+
/* @__PURE__ */ jsx8("h2", { id: `scui-subagents-${label.toLowerCase().replaceAll(" ", "-")}`, children: label }),
|
|
2396
|
+
rows.map((row) => /* @__PURE__ */ jsx8(SubagentRow, { row, inspector, adapter }, row.key))
|
|
2397
|
+
] });
|
|
2398
|
+
}
|
|
2399
|
+
function SubagentInspectorContent({ state, adapter, onClose, inspector }) {
|
|
2369
2400
|
const selected = inspector.items.find((row) => row.key === inspector.selectedKey) ?? null;
|
|
2401
|
+
const attention = inspector.items.filter((row) => ATTENTION_ACTIVITY.has(row.activity));
|
|
2402
|
+
const active = inspector.items.filter((row) => ACTIVE_ACTIVITY.has(row.activity));
|
|
2403
|
+
const finished = inspector.items.filter((row) => !ATTENTION_ACTIVITY.has(row.activity) && !ACTIVE_ACTIVITY.has(row.activity));
|
|
2404
|
+
const [finishedOpen, setFinishedOpen] = useState5(false);
|
|
2405
|
+
const backButton = useRef6(null);
|
|
2406
|
+
useEffect7(() => {
|
|
2407
|
+
if (inspector.status === "ready" && !attention.length && !active.length) setFinishedOpen(true);
|
|
2408
|
+
}, [inspector.parentKey, inspector.status]);
|
|
2409
|
+
useEffect7(() => {
|
|
2410
|
+
backButton.current?.focus({ preventScroll: true });
|
|
2411
|
+
}, [selected?.key]);
|
|
2370
2412
|
const detailState = selected ? {
|
|
2371
2413
|
...state,
|
|
2372
2414
|
transcript: inspector.transcript,
|
|
@@ -2387,15 +2429,14 @@ function SubagentInspector({ state, adapter, onClose }) {
|
|
|
2387
2429
|
onClose();
|
|
2388
2430
|
};
|
|
2389
2431
|
const back = () => selected ? adapter.onIntent({ action: "openSubagents", key: inspector.parentKey }) : leave();
|
|
2390
|
-
return /* @__PURE__ */ jsxs7("section", { className: "scui-subagents", "aria-label": `
|
|
2432
|
+
return /* @__PURE__ */ jsxs7("section", { className: "scui-subagents", "aria-label": `Agents for ${inspector.parentTitle}`, children: [
|
|
2391
2433
|
/* @__PURE__ */ jsxs7("header", { className: "scui-head", children: [
|
|
2392
|
-
/* @__PURE__ */ jsx8("button", { type: "button", "aria-label": selected ? "Back to
|
|
2393
|
-
/* @__PURE__ */ jsx8(UiIcon, { name: "agents", size: 20 }),
|
|
2434
|
+
/* @__PURE__ */ jsx8("button", { ref: backButton, type: "button", "aria-label": selected ? "Back to agents" : "Back to chats", onClick: back, children: /* @__PURE__ */ jsx8(UiIcon, { name: "back", size: 17 }) }),
|
|
2435
|
+
selected ? /* @__PURE__ */ jsx8(HarnessLogo, { id: selected.harness, activity: selected.activity, size: 24 }) : /* @__PURE__ */ jsx8(UiIcon, { name: "agents", size: 20 }),
|
|
2394
2436
|
/* @__PURE__ */ jsxs7("span", { className: "scui-head-copy", children: [
|
|
2395
2437
|
/* @__PURE__ */ jsx8("strong", { children: selected ? sessionDisplayName(selected) : `${inspector.items.length || ""} ${inspector.items.length === 1 ? "agent" : "agents"}`.trim() }),
|
|
2396
2438
|
/* @__PURE__ */ jsx8("small", { children: selected ? `${harnessDisplayName(selected.harness)} \xB7 Read-only` : inspector.parentTitle })
|
|
2397
|
-
] })
|
|
2398
|
-
/* @__PURE__ */ jsx8("button", { type: "button", "aria-label": "Close subagent inspector", onClick: leave, children: /* @__PURE__ */ jsx8(UiIcon, { name: "close", size: 18 }) })
|
|
2439
|
+
] })
|
|
2399
2440
|
] }),
|
|
2400
2441
|
inspector.status === "loading" ? /* @__PURE__ */ jsxs7("div", { className: "scui-subagents-loading", role: "status", children: [
|
|
2401
2442
|
/* @__PURE__ */ jsx8("i", {}),
|
|
@@ -2405,24 +2446,29 @@ function SubagentInspector({ state, adapter, onClose }) {
|
|
|
2405
2446
|
] })
|
|
2406
2447
|
] }) : null,
|
|
2407
2448
|
inspector.error ? /* @__PURE__ */ jsx8("div", { className: "scui-error", role: "alert", children: inspector.error }) : null,
|
|
2408
|
-
!selected && inspector.status === "ready" ? /* @__PURE__ */
|
|
2409
|
-
/* @__PURE__ */ jsx8(
|
|
2410
|
-
/* @__PURE__ */
|
|
2411
|
-
|
|
2412
|
-
/* @__PURE__ */
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2449
|
+
!selected && inspector.status === "ready" && inspector.items.length ? /* @__PURE__ */ jsxs7("div", { className: "scui-subagent-rows", children: [
|
|
2450
|
+
/* @__PURE__ */ jsx8(SubagentSection, { label: "Needs attention", rows: attention, inspector, adapter }),
|
|
2451
|
+
/* @__PURE__ */ jsx8(SubagentSection, { label: "Active", rows: active, inspector, adapter }),
|
|
2452
|
+
finished.length ? /* @__PURE__ */ jsxs7("details", { className: "scui-subagent-history", open: finishedOpen, onToggle: (event) => setFinishedOpen(event.currentTarget.open), children: [
|
|
2453
|
+
/* @__PURE__ */ jsxs7("summary", { children: [
|
|
2454
|
+
/* @__PURE__ */ jsx8("span", { children: "Finished" }),
|
|
2455
|
+
/* @__PURE__ */ jsx8("small", { children: finished.length }),
|
|
2456
|
+
/* @__PURE__ */ jsx8(UiIcon, { name: "chevron", size: 14 })
|
|
2457
|
+
] }),
|
|
2458
|
+
/* @__PURE__ */ jsx8("div", { children: finished.map((row) => /* @__PURE__ */ jsx8(SubagentRow, { row, inspector, adapter }, row.key)) })
|
|
2459
|
+
] }) : null
|
|
2460
|
+
] }) : null,
|
|
2419
2461
|
!selected && inspector.status === "ready" && !inspector.items.length ? /* @__PURE__ */ jsx8("div", { className: "scui-empty", children: "No native child sessions were found." }) : null,
|
|
2420
2462
|
selected && inspector.status === "ready" && detailState ? /* @__PURE__ */ jsx8(Conversation, { state: detailState, adapter, memoryKey: `subagent:${selected.key}` }) : null
|
|
2421
2463
|
] });
|
|
2422
2464
|
}
|
|
2465
|
+
function SubagentInspector({ state, adapter, onClose }) {
|
|
2466
|
+
if (!state.subagentInspector) return null;
|
|
2467
|
+
return /* @__PURE__ */ jsx8(SubagentInspectorContent, { state, adapter, onClose, inspector: state.subagentInspector });
|
|
2468
|
+
}
|
|
2423
2469
|
|
|
2424
2470
|
// src/settings.jsx
|
|
2425
|
-
import { useEffect as
|
|
2471
|
+
import { useEffect as useEffect8, useId as useId2, useMemo as useMemo2, useRef as useRef7, useState as useState6 } from "preact/hooks";
|
|
2426
2472
|
import { jsx as jsx9, jsxs as jsxs8 } from "preact/jsx-runtime";
|
|
2427
2473
|
function HarnessAdvisory({ state, onReview }) {
|
|
2428
2474
|
const advisory = state.interopSettings?.advisories[0];
|
|
@@ -2445,12 +2491,12 @@ function initialValues(report, recommendedChange) {
|
|
|
2445
2491
|
function HarnessSettingsPanel({ state, adapter, onClose, recommendedChange = null }) {
|
|
2446
2492
|
const report = state.interopSettings;
|
|
2447
2493
|
const titleId = useId2();
|
|
2448
|
-
const panel =
|
|
2494
|
+
const panel = useRef7(null);
|
|
2449
2495
|
const valuesKey = `${report?.revision ?? ""}:${recommendedChange?.key ?? ""}:${recommendedChange?.value ?? ""}`;
|
|
2450
2496
|
const defaults = useMemo2(() => report ? initialValues(report, recommendedChange) : {}, [valuesKey]);
|
|
2451
|
-
const [values, setValues] =
|
|
2452
|
-
|
|
2453
|
-
|
|
2497
|
+
const [values, setValues] = useState6(defaults);
|
|
2498
|
+
useEffect8(() => setValues(defaults), [defaults]);
|
|
2499
|
+
useEffect8(() => {
|
|
2454
2500
|
panel.current?.querySelector("select, button")?.focus({ preventScroll: true });
|
|
2455
2501
|
const dismiss = (event) => {
|
|
2456
2502
|
if (event.key === "Escape") {
|
|
@@ -2538,11 +2584,11 @@ function HarnessReadiness({ harnesses, adapter }) {
|
|
|
2538
2584
|
] });
|
|
2539
2585
|
}
|
|
2540
2586
|
function HarnessPicker({ harnesses, value, disabled = false, adapter, onChange, logo: Logo = HarnessLogo }) {
|
|
2541
|
-
const [open, setOpen] =
|
|
2587
|
+
const [open, setOpen] = useState6(false);
|
|
2542
2588
|
const menuId = useId2();
|
|
2543
|
-
const root =
|
|
2544
|
-
const trigger =
|
|
2545
|
-
const panel =
|
|
2589
|
+
const root = useRef7(null);
|
|
2590
|
+
const trigger = useRef7(null);
|
|
2591
|
+
const panel = useRef7(null);
|
|
2546
2592
|
const available = harnesses.filter((item) => item.startable);
|
|
2547
2593
|
const unavailable = harnesses.filter((item) => !item.startable);
|
|
2548
2594
|
const selected = available.find((item) => item.id === value) ?? available[0] ?? null;
|
|
@@ -2550,7 +2596,7 @@ function HarnessPicker({ harnesses, value, disabled = false, adapter, onChange,
|
|
|
2550
2596
|
setOpen(false);
|
|
2551
2597
|
trigger.current?.focus({ preventScroll: true });
|
|
2552
2598
|
};
|
|
2553
|
-
|
|
2599
|
+
useEffect8(() => {
|
|
2554
2600
|
if (!open) return;
|
|
2555
2601
|
panel.current?.querySelector('[aria-selected="true"], [role="option"]')?.focus({ preventScroll: true });
|
|
2556
2602
|
const dismiss = (event) => {
|
|
@@ -2612,7 +2658,7 @@ function HarnessPicker({ harnesses, value, disabled = false, adapter, onChange,
|
|
|
2612
2658
|
}
|
|
2613
2659
|
|
|
2614
2660
|
// src/messenger.jsx
|
|
2615
|
-
import { jsx as jsx10, jsxs as jsxs9 } from "preact/jsx-runtime";
|
|
2661
|
+
import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs9 } from "preact/jsx-runtime";
|
|
2616
2662
|
var pendingMessageMemory = /* @__PURE__ */ new Map();
|
|
2617
2663
|
var messengerViewMemory = /* @__PURE__ */ new Map();
|
|
2618
2664
|
var newChatMemory = /* @__PURE__ */ new Map();
|
|
@@ -2655,10 +2701,10 @@ function Receipt({ state, adapter }) {
|
|
|
2655
2701
|
return null;
|
|
2656
2702
|
}
|
|
2657
2703
|
function ConversationActions({ state, adapter, actionPending, onNew, onSettings }) {
|
|
2658
|
-
const [open, setOpen] =
|
|
2659
|
-
const root =
|
|
2660
|
-
const panel =
|
|
2661
|
-
const trigger =
|
|
2704
|
+
const [open, setOpen] = useState7(false);
|
|
2705
|
+
const root = useRef8(null);
|
|
2706
|
+
const panel = useRef8(null);
|
|
2707
|
+
const trigger = useRef8(null);
|
|
2662
2708
|
const menuId = useId3();
|
|
2663
2709
|
const targets = state.harnesses.filter((item) => item.startable);
|
|
2664
2710
|
const groups = [
|
|
@@ -2682,7 +2728,7 @@ function ConversationActions({ state, adapter, actionPending, onNew, onSettings
|
|
|
2682
2728
|
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 } })) : []
|
|
2683
2729
|
}
|
|
2684
2730
|
].filter((group) => group.items.length);
|
|
2685
|
-
|
|
2731
|
+
useEffect9(() => {
|
|
2686
2732
|
if (!open) return;
|
|
2687
2733
|
panel.current?.querySelector("button:not(:disabled)")?.focus({ preventScroll: true });
|
|
2688
2734
|
const dismiss = (event) => {
|
|
@@ -2733,11 +2779,11 @@ function ConversationActions({ state, adapter, actionPending, onNew, onSettings
|
|
|
2733
2779
|
] });
|
|
2734
2780
|
}
|
|
2735
2781
|
function ChatHeader({ state, adapter, pendingStatus, actionPending, onBack, onNew, onClose, onSettings, headerActions: HeaderActions }) {
|
|
2736
|
-
const back =
|
|
2782
|
+
const back = useRef8(null);
|
|
2737
2783
|
const harness = state.attached?.harness ?? state.harness;
|
|
2738
2784
|
const title = state.attached ? sessionDisplayName(state.attached) : harnessDisplayName(harness) || "Agent chat";
|
|
2739
2785
|
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";
|
|
2740
|
-
|
|
2786
|
+
useEffect9(() => {
|
|
2741
2787
|
if (state.mode === "mirror" && !state.canSend) back.current?.focus({ preventScroll: true });
|
|
2742
2788
|
}, []);
|
|
2743
2789
|
return /* @__PURE__ */ jsxs9("header", { className: "scui-head scui-chat-head", children: [
|
|
@@ -2760,26 +2806,26 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
2760
2806
|
const Header = slots.header;
|
|
2761
2807
|
const HeaderActions = slots.headerActions;
|
|
2762
2808
|
const memoryKey = state.attached?.key || `${state.harness}:${state.workspace}`;
|
|
2763
|
-
const [pending, setPendingState] =
|
|
2764
|
-
const [pendingAction, setPendingAction] =
|
|
2765
|
-
const [restoreDraft, setRestoreDraft] =
|
|
2766
|
-
const [settings, setSettings] =
|
|
2767
|
-
const restoreSequence =
|
|
2768
|
-
const actionSequence =
|
|
2769
|
-
const lastNavigation =
|
|
2770
|
-
const acknowledged =
|
|
2809
|
+
const [pending, setPendingState] = useState7(() => pendingMessageMemory.get(memoryKey) ?? null);
|
|
2810
|
+
const [pendingAction, setPendingAction] = useState7(null);
|
|
2811
|
+
const [restoreDraft, setRestoreDraft] = useState7(null);
|
|
2812
|
+
const [settings, setSettings] = useState7(null);
|
|
2813
|
+
const restoreSequence = useRef8(0);
|
|
2814
|
+
const actionSequence = useRef8(0);
|
|
2815
|
+
const lastNavigation = useRef8(null);
|
|
2816
|
+
const acknowledged = useRef8(/* @__PURE__ */ new Set());
|
|
2771
2817
|
const setPending = (update) => setPendingState((current) => {
|
|
2772
2818
|
const next = typeof update === "function" ? update(current) : update;
|
|
2773
2819
|
if (next) boundedSet(pendingMessageMemory, memoryKey, next);
|
|
2774
2820
|
else pendingMessageMemory.delete(memoryKey);
|
|
2775
2821
|
return next;
|
|
2776
2822
|
});
|
|
2777
|
-
|
|
2823
|
+
useEffect9(() => {
|
|
2778
2824
|
setPendingState(pendingMessageMemory.get(memoryKey) ?? null);
|
|
2779
2825
|
setPendingAction(null);
|
|
2780
2826
|
setRestoreDraft(null);
|
|
2781
2827
|
}, [memoryKey]);
|
|
2782
|
-
|
|
2828
|
+
useEffect9(() => {
|
|
2783
2829
|
if (!navigation || navigation.id === lastNavigation.current) return;
|
|
2784
2830
|
lastNavigation.current = navigation.id;
|
|
2785
2831
|
if (navigation.draft === void 0 && !navigation.context?.length && !navigation.images?.length) return;
|
|
@@ -2790,7 +2836,7 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
2790
2836
|
images: navigation.images
|
|
2791
2837
|
});
|
|
2792
2838
|
}, [navigation]);
|
|
2793
|
-
|
|
2839
|
+
useEffect9(() => {
|
|
2794
2840
|
if (!pending) return;
|
|
2795
2841
|
if (state.transcript.some((entry) => entry.role === "user" && entry.text.trim() === pending.text.trim() && !pending.baselineIds.includes(entry.id))) {
|
|
2796
2842
|
setPending(null);
|
|
@@ -2819,7 +2865,7 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
2819
2865
|
setRestoreDraft({ id: restoreSequence.current, text: pending.text, context: pending.context, images: pending.images });
|
|
2820
2866
|
setPending({ ...pending, status: "editing" });
|
|
2821
2867
|
};
|
|
2822
|
-
|
|
2868
|
+
useEffect9(() => {
|
|
2823
2869
|
const key = state.attached?.key;
|
|
2824
2870
|
if (!key || !state.attention.some((item) => item.key === key)) {
|
|
2825
2871
|
if (key) acknowledged.current.delete(key);
|
|
@@ -2854,7 +2900,7 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
2854
2900
|
return result;
|
|
2855
2901
|
}
|
|
2856
2902
|
}), [adapter, state.error]);
|
|
2857
|
-
|
|
2903
|
+
useEffect9(() => {
|
|
2858
2904
|
if (!pendingAction) return;
|
|
2859
2905
|
if (state.operation && !pendingAction.seenOperation) {
|
|
2860
2906
|
setPendingAction({ ...pendingAction, seenOperation: true });
|
|
@@ -2891,18 +2937,18 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
|
|
|
2891
2937
|
const startable = state.harnesses.filter((item) => item.startable);
|
|
2892
2938
|
const startableKey = startable.map((item) => `${item.id}:${item.launchModes?.join(",")}:${item.preferredLaunchMode ?? ""}`).join("\0");
|
|
2893
2939
|
const remembered = newChatMemory.get(memoryKey) ?? { harness: startable[0]?.id ?? "", draft: "", context: [], images: [], modes: {} };
|
|
2894
|
-
const [harness, setHarness] =
|
|
2895
|
-
const [draft, setDraft] =
|
|
2896
|
-
const [context, setContext] =
|
|
2897
|
-
const [images, setImages] =
|
|
2898
|
-
const [modes, setModes] =
|
|
2899
|
-
const [starting, setStarting] =
|
|
2900
|
-
const [picking, setPicking] =
|
|
2901
|
-
const [dragging, setDragging] =
|
|
2902
|
-
const [pickerError, setPickerError] =
|
|
2903
|
-
const startSequence =
|
|
2904
|
-
const lastComposerCommand =
|
|
2905
|
-
const textarea =
|
|
2940
|
+
const [harness, setHarness] = useState7(remembered.harness);
|
|
2941
|
+
const [draft, setDraft] = useState7(remembered.draft);
|
|
2942
|
+
const [context, setContext] = useState7(remembered.context);
|
|
2943
|
+
const [images, setImages] = useState7(remembered.images ?? []);
|
|
2944
|
+
const [modes, setModes] = useState7(remembered.modes ?? {});
|
|
2945
|
+
const [starting, setStarting] = useState7(null);
|
|
2946
|
+
const [picking, setPicking] = useState7(false);
|
|
2947
|
+
const [dragging, setDragging] = useState7(false);
|
|
2948
|
+
const [pickerError, setPickerError] = useState7(null);
|
|
2949
|
+
const startSequence = useRef8(0);
|
|
2950
|
+
const lastComposerCommand = useRef8(null);
|
|
2951
|
+
const textarea = useRef8(null);
|
|
2906
2952
|
const selectedHarness = startable.find((item) => item.id === harness) ?? null;
|
|
2907
2953
|
const Picker = components.HarnessPicker ?? HarnessPicker;
|
|
2908
2954
|
const Readiness = components.HarnessReadiness ?? HarnessReadiness;
|
|
@@ -2913,13 +2959,13 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
|
|
|
2913
2959
|
const terminalAttachments = mode === "terminal" && (context.length > 0 || images.length > 0);
|
|
2914
2960
|
const remember = (overrides = {}) => boundedSet(newChatMemory, memoryKey, { harness, draft, context, images, modes, ...overrides });
|
|
2915
2961
|
useAutosizeTextarea(textarea, draft);
|
|
2916
|
-
|
|
2962
|
+
useEffect9(() => {
|
|
2917
2963
|
if (startable.some((item) => item.id === harness)) return;
|
|
2918
2964
|
const next = startable[0]?.id ?? "";
|
|
2919
2965
|
setHarness(next);
|
|
2920
2966
|
remember({ harness: next });
|
|
2921
2967
|
}, [harness, startableKey]);
|
|
2922
|
-
|
|
2968
|
+
useEffect9(() => {
|
|
2923
2969
|
if (!starting || starting.mode === "terminal") return;
|
|
2924
2970
|
const sessionChanged = (state.attached?.key ?? null) !== starting.attachedKey;
|
|
2925
2971
|
const beganWorking = !starting.busy && state.busy;
|
|
@@ -2927,13 +2973,13 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
|
|
|
2927
2973
|
newChatMemory.delete(memoryKey);
|
|
2928
2974
|
onStarted("headless");
|
|
2929
2975
|
}, [memoryKey, onStarted, starting, state.attached?.key, state.busy]);
|
|
2930
|
-
|
|
2976
|
+
useEffect9(() => {
|
|
2931
2977
|
if (starting && state.error !== starting.initialError && !state.busy && !state.operation) setStarting(null);
|
|
2932
2978
|
}, [starting, state.busy, state.error, state.operation]);
|
|
2933
|
-
|
|
2979
|
+
useEffect9(() => {
|
|
2934
2980
|
textarea.current?.focus({ preventScroll: true });
|
|
2935
2981
|
}, []);
|
|
2936
|
-
|
|
2982
|
+
useEffect9(() => {
|
|
2937
2983
|
if (!navigation) return;
|
|
2938
2984
|
const nextHarness = startable.some((item) => item.id === navigation.harness) ? navigation.harness : harness;
|
|
2939
2985
|
const nextDraft = typeof navigation.draft === "string" ? navigation.draft : draft;
|
|
@@ -2946,7 +2992,7 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
|
|
|
2946
2992
|
remember({ harness: nextHarness, draft: nextDraft, context: nextContext, images: nextImages });
|
|
2947
2993
|
textarea.current?.focus({ preventScroll: true });
|
|
2948
2994
|
}, [navigation?.id]);
|
|
2949
|
-
|
|
2995
|
+
useEffect9(() => {
|
|
2950
2996
|
if (!composerCommand || composerCommand.id === lastComposerCommand.current) return;
|
|
2951
2997
|
lastComposerCommand.current = composerCommand.id;
|
|
2952
2998
|
if (composerCommand.action === "attach") {
|
|
@@ -3123,19 +3169,19 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
3123
3169
|
const contextCandidates = useMemo3(() => normalizeAttachmentCandidates(candidatesInput), [candidatesInput]);
|
|
3124
3170
|
const copy = { ...DEFAULT_LABELS, ...labels };
|
|
3125
3171
|
const memoryKey = state.workspace || "@default";
|
|
3126
|
-
const [view, setViewState] =
|
|
3127
|
-
const [opening, setOpening] =
|
|
3128
|
-
const [newNavigation, setNewNavigation] =
|
|
3129
|
-
const [chatNavigation, setChatNavigation] =
|
|
3130
|
-
const [listFocus, setListFocus] =
|
|
3131
|
-
const [inspecting, setInspecting] =
|
|
3132
|
-
const lastNavigation =
|
|
3172
|
+
const [view, setViewState] = useState7(initialView ?? (state.attention.length ? "list" : messengerViewMemory.get(memoryKey) ?? (state.attached || state.transcript.length ? "chat" : "list")));
|
|
3173
|
+
const [opening, setOpening] = useState7(null);
|
|
3174
|
+
const [newNavigation, setNewNavigation] = useState7(null);
|
|
3175
|
+
const [chatNavigation, setChatNavigation] = useState7(null);
|
|
3176
|
+
const [listFocus, setListFocus] = useState7(null);
|
|
3177
|
+
const [inspecting, setInspecting] = useState7(null);
|
|
3178
|
+
const lastNavigation = useRef8(null);
|
|
3133
3179
|
const setView = (next) => {
|
|
3134
3180
|
boundedSet(messengerViewMemory, memoryKey, next);
|
|
3135
3181
|
setViewState(next);
|
|
3136
3182
|
onViewChange?.(next);
|
|
3137
3183
|
};
|
|
3138
|
-
|
|
3184
|
+
useEffect9(() => {
|
|
3139
3185
|
if (!navigation || navigation.id === lastNavigation.current) return;
|
|
3140
3186
|
lastNavigation.current = navigation.id;
|
|
3141
3187
|
if (navigation.view === "list") {
|
|
@@ -3165,7 +3211,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
3165
3211
|
adapter.onIntent({ action: "attach", key: navigation.sessionKey });
|
|
3166
3212
|
}
|
|
3167
3213
|
}, [adapter, navigation, state.attached?.key, state.sessions]);
|
|
3168
|
-
|
|
3214
|
+
useEffect9(() => {
|
|
3169
3215
|
if (!opening) return;
|
|
3170
3216
|
if (state.attached?.key === opening.key) {
|
|
3171
3217
|
setOpening(null);
|
|
@@ -3193,35 +3239,36 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
3193
3239
|
...state,
|
|
3194
3240
|
subagentInspector: state.subagentInspector?.parentKey === inspectorParent.key ? state.subagentInspector : { parentKey: inspectorParent.key, parentTitle: sessionDisplayName(inspectorParent), status: "loading", items: [], selectedKey: null, transcript: [], error: null }
|
|
3195
3241
|
} : null;
|
|
3196
|
-
return /* @__PURE__ */ jsxs9("main", { className: `scui-root ${className}`, "data-view": view, "data-mode": state.mode, "aria-label": "Supercode messenger", children: [
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
/* @__PURE__ */
|
|
3215
|
-
|
|
3216
|
-
/* @__PURE__ */ jsxs9("
|
|
3217
|
-
|
|
3218
|
-
|
|
3242
|
+
return /* @__PURE__ */ jsxs9("main", { className: `scui-root ${className}`, "data-view": inspectorState ? "agents" : view, "data-mode": state.mode, "aria-label": "Supercode messenger", children: [
|
|
3243
|
+
inspectorState ? /* @__PURE__ */ jsx10(SubagentInspector, { state: inspectorState, adapter, onClose: () => setInspecting(null) }) : /* @__PURE__ */ jsxs9(Fragment5, { children: [
|
|
3244
|
+
view === "list" ? /* @__PURE__ */ jsx10(SessionList, { state, adapter, focusKey: listFocus, onOpen: open, onOpenSubagents: openSubagents, onNew: () => {
|
|
3245
|
+
setListFocus("@new");
|
|
3246
|
+
setChatNavigation(null);
|
|
3247
|
+
setNewNavigation(null);
|
|
3248
|
+
setView("new");
|
|
3249
|
+
}, onClose: adapter.onClose ? close : void 0, components, labels: copy, memoryKey, slots, headerActions: HeaderActions }) : null,
|
|
3250
|
+
view === "new" ? /* @__PURE__ */ jsx10(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,
|
|
3251
|
+
view === "chat" ? /* @__PURE__ */ jsx10(Chat, { state, adapter, onBack: () => {
|
|
3252
|
+
setListFocus(state.attached?.key ?? listFocus);
|
|
3253
|
+
setView("list");
|
|
3254
|
+
}, onNew: () => {
|
|
3255
|
+
setListFocus("@new");
|
|
3256
|
+
setChatNavigation(null);
|
|
3257
|
+
setNewNavigation(null);
|
|
3258
|
+
setView("new");
|
|
3259
|
+
}, onClose: adapter.onClose ? close : void 0, components, slots, labels: copy, contextCandidates, navigation: chatNavigation?.sessionKey === state.attached?.key ? chatNavigation : null, composerCommand }) : null,
|
|
3260
|
+
opening ? /* @__PURE__ */ jsxs9("div", { className: "scui-opening", role: "status", "aria-busy": "true", children: [
|
|
3261
|
+
/* @__PURE__ */ jsx10(HarnessLogo, { id: opening.harness, size: 34 }),
|
|
3262
|
+
/* @__PURE__ */ jsxs9("span", { children: [
|
|
3263
|
+
/* @__PURE__ */ jsxs9("strong", { children: [
|
|
3264
|
+
"Opening ",
|
|
3265
|
+
sessionDisplayName(opening)
|
|
3266
|
+
] }),
|
|
3267
|
+
/* @__PURE__ */ jsx10("small", { children: "Loading the latest transcript window\u2026" })
|
|
3219
3268
|
] }),
|
|
3220
|
-
/* @__PURE__ */ jsx10("
|
|
3221
|
-
] })
|
|
3222
|
-
|
|
3223
|
-
] }) : null,
|
|
3224
|
-
inspectorState ? /* @__PURE__ */ jsx10(SubagentInspector, { state: inspectorState, adapter, onClose: () => setInspecting(null) }) : null,
|
|
3269
|
+
/* @__PURE__ */ jsx10("i", {})
|
|
3270
|
+
] }) : null
|
|
3271
|
+
] }),
|
|
3225
3272
|
Footer ? /* @__PURE__ */ jsx10(Footer, { state, adapter, value: copy }) : null
|
|
3226
3273
|
] });
|
|
3227
3274
|
}
|