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