@volter-ai-dev/supercode-ui 0.1.38 → 0.1.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/components.mjs +24 -3
- package/embed.mjs +24 -3
- package/index.d.ts +3 -1
- package/messenger.mjs +24 -3
- package/package.json +1 -1
- package/react/components.mjs +24 -3
- package/react/messenger.mjs +24 -3
- package/react/sessions.mjs +2 -1
- package/sessions.mjs +2 -1
package/README.md
CHANGED
|
@@ -135,7 +135,7 @@ Hosts do not need to fork the messenger to connect their own object model:
|
|
|
135
135
|
```
|
|
136
136
|
|
|
137
137
|
`navigation` is an event, not duplicated router state: change its `id` to open a conversation or
|
|
138
|
-
prefill
|
|
138
|
+
prefill either an existing or new one, while `onViewChange` observes user navigation. Context candidates use the exact
|
|
139
139
|
bounded `TranscriptAttachment` envelope sent to the harness; a custom candidate component changes
|
|
140
140
|
presentation without inventing a second context protocol. `beforeSessions` and `afterSessions`
|
|
141
141
|
place host-owned rows inside the same searchable scroller. `confirmIntent` runs before resume,
|
package/components.mjs
CHANGED
|
@@ -2301,6 +2301,7 @@ function SessionList({ state, adapter, onOpen, onNew, onClose, components = {},
|
|
|
2301
2301
|
const rowScroller = useRef5(null);
|
|
2302
2302
|
const rows = filterSessions(state.sessions, query);
|
|
2303
2303
|
const Row = components.SessionRow ?? SessionRow;
|
|
2304
|
+
const ListHeader = slots.listHeader;
|
|
2304
2305
|
const BeforeSessions = slots.beforeSessions;
|
|
2305
2306
|
const AfterSessions = slots.afterSessions;
|
|
2306
2307
|
useLayoutEffect3(() => {
|
|
@@ -2327,7 +2328,7 @@ function SessionList({ state, adapter, onOpen, onNew, onClose, components = {},
|
|
|
2327
2328
|
}
|
|
2328
2329
|
};
|
|
2329
2330
|
return /* @__PURE__ */ jsxs7("section", { className: "scui-list", ref: root, children: [
|
|
2330
|
-
/* @__PURE__ */ jsxs7("header", { className: "scui-head", children: [
|
|
2331
|
+
ListHeader ? /* @__PURE__ */ jsx8(ListHeader, { state, adapter, value: { query, rows, onNew } }) : /* @__PURE__ */ jsxs7("header", { className: "scui-head", children: [
|
|
2331
2332
|
/* @__PURE__ */ jsxs7("span", { className: "scui-head-copy", children: [
|
|
2332
2333
|
/* @__PURE__ */ jsx8("strong", { children: labels.chats }),
|
|
2333
2334
|
/* @__PURE__ */ jsxs7("small", { children: [
|
|
@@ -2627,7 +2628,7 @@ function ChatHeader({ state, adapter, pendingStatus, actionPending, onBack, onNe
|
|
|
2627
2628
|
onClose ? /* @__PURE__ */ jsx10("button", { type: "button", "aria-label": "Close", onClick: onClose, children: /* @__PURE__ */ jsx10(UiIcon, { name: "close", size: 18 }) }) : null
|
|
2628
2629
|
] });
|
|
2629
2630
|
}
|
|
2630
|
-
function Chat({ state, adapter, onBack, onNew, onClose, components, slots, labels, contextCandidates }) {
|
|
2631
|
+
function Chat({ state, adapter, onBack, onNew, onClose, components, slots, labels, contextCandidates, navigation }) {
|
|
2631
2632
|
const Header = slots.header;
|
|
2632
2633
|
const HeaderActions = slots.headerActions;
|
|
2633
2634
|
const memoryKey = state.attached?.key || `${state.harness}:${state.workspace}`;
|
|
@@ -2637,6 +2638,7 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
2637
2638
|
const [settings, setSettings] = useState6(null);
|
|
2638
2639
|
const restoreSequence = useRef7(0);
|
|
2639
2640
|
const actionSequence = useRef7(0);
|
|
2641
|
+
const lastNavigation = useRef7(null);
|
|
2640
2642
|
const acknowledged = useRef7(/* @__PURE__ */ new Set());
|
|
2641
2643
|
const setPending = (update) => setPendingState((current) => {
|
|
2642
2644
|
const next = typeof update === "function" ? update(current) : update;
|
|
@@ -2649,6 +2651,17 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
2649
2651
|
setPendingAction(null);
|
|
2650
2652
|
setRestoreDraft(null);
|
|
2651
2653
|
}, [memoryKey]);
|
|
2654
|
+
useEffect8(() => {
|
|
2655
|
+
if (!navigation || navigation.id === lastNavigation.current) return;
|
|
2656
|
+
lastNavigation.current = navigation.id;
|
|
2657
|
+
if (navigation.draft === void 0 && !navigation.context?.length && !navigation.images?.length) return;
|
|
2658
|
+
setRestoreDraft({
|
|
2659
|
+
id: `host:${String(navigation.id)}`,
|
|
2660
|
+
text: navigation.draft ?? "",
|
|
2661
|
+
context: navigation.context,
|
|
2662
|
+
images: navigation.images
|
|
2663
|
+
});
|
|
2664
|
+
}, [navigation]);
|
|
2652
2665
|
useEffect8(() => {
|
|
2653
2666
|
if (!pending) return;
|
|
2654
2667
|
if (state.transcript.some((entry) => entry.role === "user" && entry.text.trim() === pending.text.trim() && !pending.baselineIds.includes(entry.id))) {
|
|
@@ -2973,6 +2986,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
2973
2986
|
const [view, setViewState] = useState6(initialView ?? (state.attention.length ? "list" : messengerViewMemory.get(memoryKey) ?? (state.attached || state.transcript.length ? "chat" : "list")));
|
|
2974
2987
|
const [opening, setOpening] = useState6(null);
|
|
2975
2988
|
const [newNavigation, setNewNavigation] = useState6(null);
|
|
2989
|
+
const [chatNavigation, setChatNavigation] = useState6(null);
|
|
2976
2990
|
const [listFocus, setListFocus] = useState6(null);
|
|
2977
2991
|
const lastNavigation = useRef7(null);
|
|
2978
2992
|
const setView = (next) => {
|
|
@@ -2985,17 +2999,21 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
2985
2999
|
lastNavigation.current = navigation.id;
|
|
2986
3000
|
if (navigation.view === "list") {
|
|
2987
3001
|
setOpening(null);
|
|
3002
|
+
setChatNavigation(null);
|
|
2988
3003
|
setView("list");
|
|
2989
3004
|
return;
|
|
2990
3005
|
}
|
|
2991
3006
|
if (navigation.view === "new") {
|
|
2992
3007
|
setListFocus("@new");
|
|
3008
|
+
setChatNavigation(null);
|
|
2993
3009
|
setNewNavigation(navigation);
|
|
2994
3010
|
setView("new");
|
|
2995
3011
|
return;
|
|
2996
3012
|
}
|
|
2997
3013
|
if (navigation.view === "chat" && typeof navigation.sessionKey === "string" && navigation.sessionKey) {
|
|
2998
3014
|
setListFocus(navigation.sessionKey);
|
|
3015
|
+
setNewNavigation(null);
|
|
3016
|
+
setChatNavigation(navigation);
|
|
2999
3017
|
if (state.attached?.key === navigation.sessionKey) {
|
|
3000
3018
|
setOpening(null);
|
|
3001
3019
|
setView("chat");
|
|
@@ -3017,6 +3035,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
3017
3035
|
}, [opening, state.attachError?.key, state.attached?.key, state.error, state.operation]);
|
|
3018
3036
|
const open = (row) => {
|
|
3019
3037
|
setListFocus(row.key);
|
|
3038
|
+
setChatNavigation(null);
|
|
3020
3039
|
setOpening(row);
|
|
3021
3040
|
adapter.onIntent({ action: "attach", key: row.key });
|
|
3022
3041
|
};
|
|
@@ -3026,6 +3045,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
3026
3045
|
return /* @__PURE__ */ jsxs9("main", { className: `scui-root ${className}`, "data-view": view, "data-mode": state.mode, "aria-label": "Supercode messenger", children: [
|
|
3027
3046
|
view === "list" ? /* @__PURE__ */ jsx10(SessionList, { state, adapter, focusKey: listFocus, onOpen: open, onNew: () => {
|
|
3028
3047
|
setListFocus("@new");
|
|
3048
|
+
setChatNavigation(null);
|
|
3029
3049
|
setNewNavigation(null);
|
|
3030
3050
|
setView("new");
|
|
3031
3051
|
}, onClose: adapter.onClose ? close : void 0, components, labels: copy, memoryKey, slots, headerActions: HeaderActions }) : null,
|
|
@@ -3035,9 +3055,10 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
3035
3055
|
setView("list");
|
|
3036
3056
|
}, onNew: () => {
|
|
3037
3057
|
setListFocus("@new");
|
|
3058
|
+
setChatNavigation(null);
|
|
3038
3059
|
setNewNavigation(null);
|
|
3039
3060
|
setView("new");
|
|
3040
|
-
}, onClose: adapter.onClose ? close : void 0, components, slots, labels: copy, contextCandidates }) : null,
|
|
3061
|
+
}, onClose: adapter.onClose ? close : void 0, components, slots, labels: copy, contextCandidates, navigation: chatNavigation?.sessionKey === state.attached?.key ? chatNavigation : null }) : null,
|
|
3041
3062
|
opening ? /* @__PURE__ */ jsxs9("div", { className: "scui-opening", role: "status", "aria-busy": "true", children: [
|
|
3042
3063
|
/* @__PURE__ */ jsx10(HarnessLogo, { id: opening.harness, size: 34 }),
|
|
3043
3064
|
/* @__PURE__ */ jsxs9("span", { children: [
|
package/embed.mjs
CHANGED
|
@@ -2221,6 +2221,7 @@ function SessionList({ state, adapter, onOpen, onNew, onClose, components = {},
|
|
|
2221
2221
|
const rowScroller = useRef5(null);
|
|
2222
2222
|
const rows = filterSessions(state.sessions, query);
|
|
2223
2223
|
const Row = components.SessionRow ?? SessionRow;
|
|
2224
|
+
const ListHeader = slots.listHeader;
|
|
2224
2225
|
const BeforeSessions = slots.beforeSessions;
|
|
2225
2226
|
const AfterSessions = slots.afterSessions;
|
|
2226
2227
|
useLayoutEffect3(() => {
|
|
@@ -2247,7 +2248,7 @@ function SessionList({ state, adapter, onOpen, onNew, onClose, components = {},
|
|
|
2247
2248
|
}
|
|
2248
2249
|
};
|
|
2249
2250
|
return /* @__PURE__ */ jsxs6("section", { className: "scui-list", ref: root, children: [
|
|
2250
|
-
/* @__PURE__ */ jsxs6("header", { className: "scui-head", children: [
|
|
2251
|
+
ListHeader ? /* @__PURE__ */ jsx7(ListHeader, { state, adapter, value: { query, rows, onNew } }) : /* @__PURE__ */ jsxs6("header", { className: "scui-head", children: [
|
|
2251
2252
|
/* @__PURE__ */ jsxs6("span", { className: "scui-head-copy", children: [
|
|
2252
2253
|
/* @__PURE__ */ jsx7("strong", { children: labels.chats }),
|
|
2253
2254
|
/* @__PURE__ */ jsxs6("small", { children: [
|
|
@@ -2547,7 +2548,7 @@ function ChatHeader({ state, adapter, pendingStatus, actionPending, onBack, onNe
|
|
|
2547
2548
|
onClose ? /* @__PURE__ */ jsx9("button", { type: "button", "aria-label": "Close", onClick: onClose, children: /* @__PURE__ */ jsx9(UiIcon, { name: "close", size: 18 }) }) : null
|
|
2548
2549
|
] });
|
|
2549
2550
|
}
|
|
2550
|
-
function Chat({ state, adapter, onBack, onNew, onClose, components, slots, labels, contextCandidates }) {
|
|
2551
|
+
function Chat({ state, adapter, onBack, onNew, onClose, components, slots, labels, contextCandidates, navigation }) {
|
|
2551
2552
|
const Header = slots.header;
|
|
2552
2553
|
const HeaderActions = slots.headerActions;
|
|
2553
2554
|
const memoryKey = state.attached?.key || `${state.harness}:${state.workspace}`;
|
|
@@ -2557,6 +2558,7 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
2557
2558
|
const [settings, setSettings] = useState6(null);
|
|
2558
2559
|
const restoreSequence = useRef7(0);
|
|
2559
2560
|
const actionSequence = useRef7(0);
|
|
2561
|
+
const lastNavigation = useRef7(null);
|
|
2560
2562
|
const acknowledged = useRef7(/* @__PURE__ */ new Set());
|
|
2561
2563
|
const setPending = (update) => setPendingState((current) => {
|
|
2562
2564
|
const next = typeof update === "function" ? update(current) : update;
|
|
@@ -2569,6 +2571,17 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
2569
2571
|
setPendingAction(null);
|
|
2570
2572
|
setRestoreDraft(null);
|
|
2571
2573
|
}, [memoryKey]);
|
|
2574
|
+
useEffect8(() => {
|
|
2575
|
+
if (!navigation || navigation.id === lastNavigation.current) return;
|
|
2576
|
+
lastNavigation.current = navigation.id;
|
|
2577
|
+
if (navigation.draft === void 0 && !navigation.context?.length && !navigation.images?.length) return;
|
|
2578
|
+
setRestoreDraft({
|
|
2579
|
+
id: `host:${String(navigation.id)}`,
|
|
2580
|
+
text: navigation.draft ?? "",
|
|
2581
|
+
context: navigation.context,
|
|
2582
|
+
images: navigation.images
|
|
2583
|
+
});
|
|
2584
|
+
}, [navigation]);
|
|
2572
2585
|
useEffect8(() => {
|
|
2573
2586
|
if (!pending) return;
|
|
2574
2587
|
if (state.transcript.some((entry) => entry.role === "user" && entry.text.trim() === pending.text.trim() && !pending.baselineIds.includes(entry.id))) {
|
|
@@ -2893,6 +2906,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
2893
2906
|
const [view, setViewState] = useState6(initialView ?? (state.attention.length ? "list" : messengerViewMemory.get(memoryKey) ?? (state.attached || state.transcript.length ? "chat" : "list")));
|
|
2894
2907
|
const [opening, setOpening] = useState6(null);
|
|
2895
2908
|
const [newNavigation, setNewNavigation] = useState6(null);
|
|
2909
|
+
const [chatNavigation, setChatNavigation] = useState6(null);
|
|
2896
2910
|
const [listFocus, setListFocus] = useState6(null);
|
|
2897
2911
|
const lastNavigation = useRef7(null);
|
|
2898
2912
|
const setView = (next) => {
|
|
@@ -2905,17 +2919,21 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
2905
2919
|
lastNavigation.current = navigation.id;
|
|
2906
2920
|
if (navigation.view === "list") {
|
|
2907
2921
|
setOpening(null);
|
|
2922
|
+
setChatNavigation(null);
|
|
2908
2923
|
setView("list");
|
|
2909
2924
|
return;
|
|
2910
2925
|
}
|
|
2911
2926
|
if (navigation.view === "new") {
|
|
2912
2927
|
setListFocus("@new");
|
|
2928
|
+
setChatNavigation(null);
|
|
2913
2929
|
setNewNavigation(navigation);
|
|
2914
2930
|
setView("new");
|
|
2915
2931
|
return;
|
|
2916
2932
|
}
|
|
2917
2933
|
if (navigation.view === "chat" && typeof navigation.sessionKey === "string" && navigation.sessionKey) {
|
|
2918
2934
|
setListFocus(navigation.sessionKey);
|
|
2935
|
+
setNewNavigation(null);
|
|
2936
|
+
setChatNavigation(navigation);
|
|
2919
2937
|
if (state.attached?.key === navigation.sessionKey) {
|
|
2920
2938
|
setOpening(null);
|
|
2921
2939
|
setView("chat");
|
|
@@ -2937,6 +2955,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
2937
2955
|
}, [opening, state.attachError?.key, state.attached?.key, state.error, state.operation]);
|
|
2938
2956
|
const open = (row) => {
|
|
2939
2957
|
setListFocus(row.key);
|
|
2958
|
+
setChatNavigation(null);
|
|
2940
2959
|
setOpening(row);
|
|
2941
2960
|
adapter.onIntent({ action: "attach", key: row.key });
|
|
2942
2961
|
};
|
|
@@ -2946,6 +2965,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
2946
2965
|
return /* @__PURE__ */ jsxs8("main", { className: `scui-root ${className}`, "data-view": view, "data-mode": state.mode, "aria-label": "Supercode messenger", children: [
|
|
2947
2966
|
view === "list" ? /* @__PURE__ */ jsx9(SessionList, { state, adapter, focusKey: listFocus, onOpen: open, onNew: () => {
|
|
2948
2967
|
setListFocus("@new");
|
|
2968
|
+
setChatNavigation(null);
|
|
2949
2969
|
setNewNavigation(null);
|
|
2950
2970
|
setView("new");
|
|
2951
2971
|
}, onClose: adapter.onClose ? close : void 0, components, labels: copy, memoryKey, slots, headerActions: HeaderActions }) : null,
|
|
@@ -2955,9 +2975,10 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
2955
2975
|
setView("list");
|
|
2956
2976
|
}, onNew: () => {
|
|
2957
2977
|
setListFocus("@new");
|
|
2978
|
+
setChatNavigation(null);
|
|
2958
2979
|
setNewNavigation(null);
|
|
2959
2980
|
setView("new");
|
|
2960
|
-
}, onClose: adapter.onClose ? close : void 0, components, slots, labels: copy, contextCandidates }) : null,
|
|
2981
|
+
}, onClose: adapter.onClose ? close : void 0, components, slots, labels: copy, contextCandidates, navigation: chatNavigation?.sessionKey === state.attached?.key ? chatNavigation : null }) : null,
|
|
2961
2982
|
opening ? /* @__PURE__ */ jsxs8("div", { className: "scui-opening", role: "status", "aria-busy": "true", children: [
|
|
2962
2983
|
/* @__PURE__ */ jsx9(HarnessLogo, { id: opening.harness, size: 34 }),
|
|
2963
2984
|
/* @__PURE__ */ jsxs8("span", { children: [
|
package/index.d.ts
CHANGED
|
@@ -455,6 +455,8 @@ export interface AgentActivityLauncherProps {
|
|
|
455
455
|
|
|
456
456
|
export interface MessengerSlots {
|
|
457
457
|
header?: ComponentType<ComponentOverrideProps>;
|
|
458
|
+
/** Replace the conversation-list header. A component returning `null` delegates all list chrome to its host. */
|
|
459
|
+
listHeader?: ComponentType<ComponentOverrideProps<{ query: string; rows: SessionRowModel[]; onNew?(): void }>>;
|
|
458
460
|
/** Add a compact consumer control to every default messenger header. `value` is the current view. */
|
|
459
461
|
headerActions?: ComponentType<ComponentOverrideProps<'list' | 'chat' | 'new'>>;
|
|
460
462
|
/** Host-owned rows rendered inside the searchable conversation scroller. */
|
|
@@ -468,7 +470,7 @@ export interface MessengerSlots {
|
|
|
468
470
|
|
|
469
471
|
export type MessengerNavigation =
|
|
470
472
|
| { id: string | number; view: 'list' }
|
|
471
|
-
| { id: string | number; view: 'chat'; sessionKey: string }
|
|
473
|
+
| { id: string | number; view: 'chat'; sessionKey: string; draft?: string; context?: TranscriptContext[]; images?: Array<TranscriptImage & { url: string }> }
|
|
472
474
|
| { id: string | number; view: 'new'; harness?: HarnessId; draft?: string; context?: TranscriptContext[]; images?: Array<TranscriptImage & { url: string }> };
|
|
473
475
|
|
|
474
476
|
export interface MessengerProps {
|
package/messenger.mjs
CHANGED
|
@@ -2218,6 +2218,7 @@ function SessionList({ state, adapter, onOpen, onNew, onClose, components = {},
|
|
|
2218
2218
|
const rowScroller = useRef5(null);
|
|
2219
2219
|
const rows = filterSessions(state.sessions, query);
|
|
2220
2220
|
const Row = components.SessionRow ?? SessionRow;
|
|
2221
|
+
const ListHeader = slots.listHeader;
|
|
2221
2222
|
const BeforeSessions = slots.beforeSessions;
|
|
2222
2223
|
const AfterSessions = slots.afterSessions;
|
|
2223
2224
|
useLayoutEffect3(() => {
|
|
@@ -2244,7 +2245,7 @@ function SessionList({ state, adapter, onOpen, onNew, onClose, components = {},
|
|
|
2244
2245
|
}
|
|
2245
2246
|
};
|
|
2246
2247
|
return /* @__PURE__ */ jsxs6("section", { className: "scui-list", ref: root, children: [
|
|
2247
|
-
/* @__PURE__ */ jsxs6("header", { className: "scui-head", children: [
|
|
2248
|
+
ListHeader ? /* @__PURE__ */ jsx7(ListHeader, { state, adapter, value: { query, rows, onNew } }) : /* @__PURE__ */ jsxs6("header", { className: "scui-head", children: [
|
|
2248
2249
|
/* @__PURE__ */ jsxs6("span", { className: "scui-head-copy", children: [
|
|
2249
2250
|
/* @__PURE__ */ jsx7("strong", { children: labels.chats }),
|
|
2250
2251
|
/* @__PURE__ */ jsxs6("small", { children: [
|
|
@@ -2544,7 +2545,7 @@ function ChatHeader({ state, adapter, pendingStatus, actionPending, onBack, onNe
|
|
|
2544
2545
|
onClose ? /* @__PURE__ */ jsx9("button", { type: "button", "aria-label": "Close", onClick: onClose, children: /* @__PURE__ */ jsx9(UiIcon, { name: "close", size: 18 }) }) : null
|
|
2545
2546
|
] });
|
|
2546
2547
|
}
|
|
2547
|
-
function Chat({ state, adapter, onBack, onNew, onClose, components, slots, labels, contextCandidates }) {
|
|
2548
|
+
function Chat({ state, adapter, onBack, onNew, onClose, components, slots, labels, contextCandidates, navigation }) {
|
|
2548
2549
|
const Header = slots.header;
|
|
2549
2550
|
const HeaderActions = slots.headerActions;
|
|
2550
2551
|
const memoryKey = state.attached?.key || `${state.harness}:${state.workspace}`;
|
|
@@ -2554,6 +2555,7 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
2554
2555
|
const [settings, setSettings] = useState6(null);
|
|
2555
2556
|
const restoreSequence = useRef7(0);
|
|
2556
2557
|
const actionSequence = useRef7(0);
|
|
2558
|
+
const lastNavigation = useRef7(null);
|
|
2557
2559
|
const acknowledged = useRef7(/* @__PURE__ */ new Set());
|
|
2558
2560
|
const setPending = (update) => setPendingState((current) => {
|
|
2559
2561
|
const next = typeof update === "function" ? update(current) : update;
|
|
@@ -2566,6 +2568,17 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
2566
2568
|
setPendingAction(null);
|
|
2567
2569
|
setRestoreDraft(null);
|
|
2568
2570
|
}, [memoryKey]);
|
|
2571
|
+
useEffect8(() => {
|
|
2572
|
+
if (!navigation || navigation.id === lastNavigation.current) return;
|
|
2573
|
+
lastNavigation.current = navigation.id;
|
|
2574
|
+
if (navigation.draft === void 0 && !navigation.context?.length && !navigation.images?.length) return;
|
|
2575
|
+
setRestoreDraft({
|
|
2576
|
+
id: `host:${String(navigation.id)}`,
|
|
2577
|
+
text: navigation.draft ?? "",
|
|
2578
|
+
context: navigation.context,
|
|
2579
|
+
images: navigation.images
|
|
2580
|
+
});
|
|
2581
|
+
}, [navigation]);
|
|
2569
2582
|
useEffect8(() => {
|
|
2570
2583
|
if (!pending) return;
|
|
2571
2584
|
if (state.transcript.some((entry) => entry.role === "user" && entry.text.trim() === pending.text.trim() && !pending.baselineIds.includes(entry.id))) {
|
|
@@ -2890,6 +2903,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
2890
2903
|
const [view, setViewState] = useState6(initialView ?? (state.attention.length ? "list" : messengerViewMemory.get(memoryKey) ?? (state.attached || state.transcript.length ? "chat" : "list")));
|
|
2891
2904
|
const [opening, setOpening] = useState6(null);
|
|
2892
2905
|
const [newNavigation, setNewNavigation] = useState6(null);
|
|
2906
|
+
const [chatNavigation, setChatNavigation] = useState6(null);
|
|
2893
2907
|
const [listFocus, setListFocus] = useState6(null);
|
|
2894
2908
|
const lastNavigation = useRef7(null);
|
|
2895
2909
|
const setView = (next) => {
|
|
@@ -2902,17 +2916,21 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
2902
2916
|
lastNavigation.current = navigation.id;
|
|
2903
2917
|
if (navigation.view === "list") {
|
|
2904
2918
|
setOpening(null);
|
|
2919
|
+
setChatNavigation(null);
|
|
2905
2920
|
setView("list");
|
|
2906
2921
|
return;
|
|
2907
2922
|
}
|
|
2908
2923
|
if (navigation.view === "new") {
|
|
2909
2924
|
setListFocus("@new");
|
|
2925
|
+
setChatNavigation(null);
|
|
2910
2926
|
setNewNavigation(navigation);
|
|
2911
2927
|
setView("new");
|
|
2912
2928
|
return;
|
|
2913
2929
|
}
|
|
2914
2930
|
if (navigation.view === "chat" && typeof navigation.sessionKey === "string" && navigation.sessionKey) {
|
|
2915
2931
|
setListFocus(navigation.sessionKey);
|
|
2932
|
+
setNewNavigation(null);
|
|
2933
|
+
setChatNavigation(navigation);
|
|
2916
2934
|
if (state.attached?.key === navigation.sessionKey) {
|
|
2917
2935
|
setOpening(null);
|
|
2918
2936
|
setView("chat");
|
|
@@ -2934,6 +2952,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
2934
2952
|
}, [opening, state.attachError?.key, state.attached?.key, state.error, state.operation]);
|
|
2935
2953
|
const open = (row) => {
|
|
2936
2954
|
setListFocus(row.key);
|
|
2955
|
+
setChatNavigation(null);
|
|
2937
2956
|
setOpening(row);
|
|
2938
2957
|
adapter.onIntent({ action: "attach", key: row.key });
|
|
2939
2958
|
};
|
|
@@ -2943,6 +2962,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
2943
2962
|
return /* @__PURE__ */ jsxs8("main", { className: `scui-root ${className}`, "data-view": view, "data-mode": state.mode, "aria-label": "Supercode messenger", children: [
|
|
2944
2963
|
view === "list" ? /* @__PURE__ */ jsx9(SessionList, { state, adapter, focusKey: listFocus, onOpen: open, onNew: () => {
|
|
2945
2964
|
setListFocus("@new");
|
|
2965
|
+
setChatNavigation(null);
|
|
2946
2966
|
setNewNavigation(null);
|
|
2947
2967
|
setView("new");
|
|
2948
2968
|
}, onClose: adapter.onClose ? close : void 0, components, labels: copy, memoryKey, slots, headerActions: HeaderActions }) : null,
|
|
@@ -2952,9 +2972,10 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
2952
2972
|
setView("list");
|
|
2953
2973
|
}, onNew: () => {
|
|
2954
2974
|
setListFocus("@new");
|
|
2975
|
+
setChatNavigation(null);
|
|
2955
2976
|
setNewNavigation(null);
|
|
2956
2977
|
setView("new");
|
|
2957
|
-
}, onClose: adapter.onClose ? close : void 0, components, slots, labels: copy, contextCandidates }) : null,
|
|
2978
|
+
}, onClose: adapter.onClose ? close : void 0, components, slots, labels: copy, contextCandidates, navigation: chatNavigation?.sessionKey === state.attached?.key ? chatNavigation : null }) : null,
|
|
2958
2979
|
opening ? /* @__PURE__ */ jsxs8("div", { className: "scui-opening", role: "status", "aria-busy": "true", children: [
|
|
2959
2980
|
/* @__PURE__ */ jsx9(HarnessLogo, { id: opening.harness, size: 34 }),
|
|
2960
2981
|
/* @__PURE__ */ jsxs8("span", { children: [
|
package/package.json
CHANGED
package/react/components.mjs
CHANGED
|
@@ -2301,6 +2301,7 @@ function SessionList({ state, adapter, onOpen, onNew, onClose, components = {},
|
|
|
2301
2301
|
const rowScroller = useRef5(null);
|
|
2302
2302
|
const rows = filterSessions(state.sessions, query);
|
|
2303
2303
|
const Row = components.SessionRow ?? SessionRow;
|
|
2304
|
+
const ListHeader = slots.listHeader;
|
|
2304
2305
|
const BeforeSessions = slots.beforeSessions;
|
|
2305
2306
|
const AfterSessions = slots.afterSessions;
|
|
2306
2307
|
useLayoutEffect3(() => {
|
|
@@ -2327,7 +2328,7 @@ function SessionList({ state, adapter, onOpen, onNew, onClose, components = {},
|
|
|
2327
2328
|
}
|
|
2328
2329
|
};
|
|
2329
2330
|
return /* @__PURE__ */ jsxs7("section", { className: "scui-list", ref: root, children: [
|
|
2330
|
-
/* @__PURE__ */ jsxs7("header", { className: "scui-head", children: [
|
|
2331
|
+
ListHeader ? /* @__PURE__ */ jsx8(ListHeader, { state, adapter, value: { query, rows, onNew } }) : /* @__PURE__ */ jsxs7("header", { className: "scui-head", children: [
|
|
2331
2332
|
/* @__PURE__ */ jsxs7("span", { className: "scui-head-copy", children: [
|
|
2332
2333
|
/* @__PURE__ */ jsx8("strong", { children: labels.chats }),
|
|
2333
2334
|
/* @__PURE__ */ jsxs7("small", { children: [
|
|
@@ -2627,7 +2628,7 @@ function ChatHeader({ state, adapter, pendingStatus, actionPending, onBack, onNe
|
|
|
2627
2628
|
onClose ? /* @__PURE__ */ jsx10("button", { type: "button", "aria-label": "Close", onClick: onClose, children: /* @__PURE__ */ jsx10(UiIcon, { name: "close", size: 18 }) }) : null
|
|
2628
2629
|
] });
|
|
2629
2630
|
}
|
|
2630
|
-
function Chat({ state, adapter, onBack, onNew, onClose, components, slots, labels, contextCandidates }) {
|
|
2631
|
+
function Chat({ state, adapter, onBack, onNew, onClose, components, slots, labels, contextCandidates, navigation }) {
|
|
2631
2632
|
const Header = slots.header;
|
|
2632
2633
|
const HeaderActions = slots.headerActions;
|
|
2633
2634
|
const memoryKey = state.attached?.key || `${state.harness}:${state.workspace}`;
|
|
@@ -2637,6 +2638,7 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
2637
2638
|
const [settings, setSettings] = useState6(null);
|
|
2638
2639
|
const restoreSequence = useRef7(0);
|
|
2639
2640
|
const actionSequence = useRef7(0);
|
|
2641
|
+
const lastNavigation = useRef7(null);
|
|
2640
2642
|
const acknowledged = useRef7(/* @__PURE__ */ new Set());
|
|
2641
2643
|
const setPending = (update) => setPendingState((current) => {
|
|
2642
2644
|
const next = typeof update === "function" ? update(current) : update;
|
|
@@ -2649,6 +2651,17 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
2649
2651
|
setPendingAction(null);
|
|
2650
2652
|
setRestoreDraft(null);
|
|
2651
2653
|
}, [memoryKey]);
|
|
2654
|
+
useEffect8(() => {
|
|
2655
|
+
if (!navigation || navigation.id === lastNavigation.current) return;
|
|
2656
|
+
lastNavigation.current = navigation.id;
|
|
2657
|
+
if (navigation.draft === void 0 && !navigation.context?.length && !navigation.images?.length) return;
|
|
2658
|
+
setRestoreDraft({
|
|
2659
|
+
id: `host:${String(navigation.id)}`,
|
|
2660
|
+
text: navigation.draft ?? "",
|
|
2661
|
+
context: navigation.context,
|
|
2662
|
+
images: navigation.images
|
|
2663
|
+
});
|
|
2664
|
+
}, [navigation]);
|
|
2652
2665
|
useEffect8(() => {
|
|
2653
2666
|
if (!pending) return;
|
|
2654
2667
|
if (state.transcript.some((entry) => entry.role === "user" && entry.text.trim() === pending.text.trim() && !pending.baselineIds.includes(entry.id))) {
|
|
@@ -2973,6 +2986,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
2973
2986
|
const [view, setViewState] = useState6(initialView ?? (state.attention.length ? "list" : messengerViewMemory.get(memoryKey) ?? (state.attached || state.transcript.length ? "chat" : "list")));
|
|
2974
2987
|
const [opening, setOpening] = useState6(null);
|
|
2975
2988
|
const [newNavigation, setNewNavigation] = useState6(null);
|
|
2989
|
+
const [chatNavigation, setChatNavigation] = useState6(null);
|
|
2976
2990
|
const [listFocus, setListFocus] = useState6(null);
|
|
2977
2991
|
const lastNavigation = useRef7(null);
|
|
2978
2992
|
const setView = (next) => {
|
|
@@ -2985,17 +2999,21 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
2985
2999
|
lastNavigation.current = navigation.id;
|
|
2986
3000
|
if (navigation.view === "list") {
|
|
2987
3001
|
setOpening(null);
|
|
3002
|
+
setChatNavigation(null);
|
|
2988
3003
|
setView("list");
|
|
2989
3004
|
return;
|
|
2990
3005
|
}
|
|
2991
3006
|
if (navigation.view === "new") {
|
|
2992
3007
|
setListFocus("@new");
|
|
3008
|
+
setChatNavigation(null);
|
|
2993
3009
|
setNewNavigation(navigation);
|
|
2994
3010
|
setView("new");
|
|
2995
3011
|
return;
|
|
2996
3012
|
}
|
|
2997
3013
|
if (navigation.view === "chat" && typeof navigation.sessionKey === "string" && navigation.sessionKey) {
|
|
2998
3014
|
setListFocus(navigation.sessionKey);
|
|
3015
|
+
setNewNavigation(null);
|
|
3016
|
+
setChatNavigation(navigation);
|
|
2999
3017
|
if (state.attached?.key === navigation.sessionKey) {
|
|
3000
3018
|
setOpening(null);
|
|
3001
3019
|
setView("chat");
|
|
@@ -3017,6 +3035,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
3017
3035
|
}, [opening, state.attachError?.key, state.attached?.key, state.error, state.operation]);
|
|
3018
3036
|
const open = (row) => {
|
|
3019
3037
|
setListFocus(row.key);
|
|
3038
|
+
setChatNavigation(null);
|
|
3020
3039
|
setOpening(row);
|
|
3021
3040
|
adapter.onIntent({ action: "attach", key: row.key });
|
|
3022
3041
|
};
|
|
@@ -3026,6 +3045,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
3026
3045
|
return /* @__PURE__ */ jsxs9("main", { className: `scui-root ${className}`, "data-view": view, "data-mode": state.mode, "aria-label": "Supercode messenger", children: [
|
|
3027
3046
|
view === "list" ? /* @__PURE__ */ jsx10(SessionList, { state, adapter, focusKey: listFocus, onOpen: open, onNew: () => {
|
|
3028
3047
|
setListFocus("@new");
|
|
3048
|
+
setChatNavigation(null);
|
|
3029
3049
|
setNewNavigation(null);
|
|
3030
3050
|
setView("new");
|
|
3031
3051
|
}, onClose: adapter.onClose ? close : void 0, components, labels: copy, memoryKey, slots, headerActions: HeaderActions }) : null,
|
|
@@ -3035,9 +3055,10 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
3035
3055
|
setView("list");
|
|
3036
3056
|
}, onNew: () => {
|
|
3037
3057
|
setListFocus("@new");
|
|
3058
|
+
setChatNavigation(null);
|
|
3038
3059
|
setNewNavigation(null);
|
|
3039
3060
|
setView("new");
|
|
3040
|
-
}, onClose: adapter.onClose ? close : void 0, components, slots, labels: copy, contextCandidates }) : null,
|
|
3061
|
+
}, onClose: adapter.onClose ? close : void 0, components, slots, labels: copy, contextCandidates, navigation: chatNavigation?.sessionKey === state.attached?.key ? chatNavigation : null }) : null,
|
|
3041
3062
|
opening ? /* @__PURE__ */ jsxs9("div", { className: "scui-opening", role: "status", "aria-busy": "true", children: [
|
|
3042
3063
|
/* @__PURE__ */ jsx10(HarnessLogo, { id: opening.harness, size: 34 }),
|
|
3043
3064
|
/* @__PURE__ */ jsxs9("span", { children: [
|
package/react/messenger.mjs
CHANGED
|
@@ -2218,6 +2218,7 @@ function SessionList({ state, adapter, onOpen, onNew, onClose, components = {},
|
|
|
2218
2218
|
const rowScroller = useRef5(null);
|
|
2219
2219
|
const rows = filterSessions(state.sessions, query);
|
|
2220
2220
|
const Row = components.SessionRow ?? SessionRow;
|
|
2221
|
+
const ListHeader = slots.listHeader;
|
|
2221
2222
|
const BeforeSessions = slots.beforeSessions;
|
|
2222
2223
|
const AfterSessions = slots.afterSessions;
|
|
2223
2224
|
useLayoutEffect3(() => {
|
|
@@ -2244,7 +2245,7 @@ function SessionList({ state, adapter, onOpen, onNew, onClose, components = {},
|
|
|
2244
2245
|
}
|
|
2245
2246
|
};
|
|
2246
2247
|
return /* @__PURE__ */ jsxs6("section", { className: "scui-list", ref: root, children: [
|
|
2247
|
-
/* @__PURE__ */ jsxs6("header", { className: "scui-head", children: [
|
|
2248
|
+
ListHeader ? /* @__PURE__ */ jsx7(ListHeader, { state, adapter, value: { query, rows, onNew } }) : /* @__PURE__ */ jsxs6("header", { className: "scui-head", children: [
|
|
2248
2249
|
/* @__PURE__ */ jsxs6("span", { className: "scui-head-copy", children: [
|
|
2249
2250
|
/* @__PURE__ */ jsx7("strong", { children: labels.chats }),
|
|
2250
2251
|
/* @__PURE__ */ jsxs6("small", { children: [
|
|
@@ -2544,7 +2545,7 @@ function ChatHeader({ state, adapter, pendingStatus, actionPending, onBack, onNe
|
|
|
2544
2545
|
onClose ? /* @__PURE__ */ jsx9("button", { type: "button", "aria-label": "Close", onClick: onClose, children: /* @__PURE__ */ jsx9(UiIcon, { name: "close", size: 18 }) }) : null
|
|
2545
2546
|
] });
|
|
2546
2547
|
}
|
|
2547
|
-
function Chat({ state, adapter, onBack, onNew, onClose, components, slots, labels, contextCandidates }) {
|
|
2548
|
+
function Chat({ state, adapter, onBack, onNew, onClose, components, slots, labels, contextCandidates, navigation }) {
|
|
2548
2549
|
const Header = slots.header;
|
|
2549
2550
|
const HeaderActions = slots.headerActions;
|
|
2550
2551
|
const memoryKey = state.attached?.key || `${state.harness}:${state.workspace}`;
|
|
@@ -2554,6 +2555,7 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
2554
2555
|
const [settings, setSettings] = useState6(null);
|
|
2555
2556
|
const restoreSequence = useRef7(0);
|
|
2556
2557
|
const actionSequence = useRef7(0);
|
|
2558
|
+
const lastNavigation = useRef7(null);
|
|
2557
2559
|
const acknowledged = useRef7(/* @__PURE__ */ new Set());
|
|
2558
2560
|
const setPending = (update) => setPendingState((current) => {
|
|
2559
2561
|
const next = typeof update === "function" ? update(current) : update;
|
|
@@ -2566,6 +2568,17 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
|
|
|
2566
2568
|
setPendingAction(null);
|
|
2567
2569
|
setRestoreDraft(null);
|
|
2568
2570
|
}, [memoryKey]);
|
|
2571
|
+
useEffect8(() => {
|
|
2572
|
+
if (!navigation || navigation.id === lastNavigation.current) return;
|
|
2573
|
+
lastNavigation.current = navigation.id;
|
|
2574
|
+
if (navigation.draft === void 0 && !navigation.context?.length && !navigation.images?.length) return;
|
|
2575
|
+
setRestoreDraft({
|
|
2576
|
+
id: `host:${String(navigation.id)}`,
|
|
2577
|
+
text: navigation.draft ?? "",
|
|
2578
|
+
context: navigation.context,
|
|
2579
|
+
images: navigation.images
|
|
2580
|
+
});
|
|
2581
|
+
}, [navigation]);
|
|
2569
2582
|
useEffect8(() => {
|
|
2570
2583
|
if (!pending) return;
|
|
2571
2584
|
if (state.transcript.some((entry) => entry.role === "user" && entry.text.trim() === pending.text.trim() && !pending.baselineIds.includes(entry.id))) {
|
|
@@ -2890,6 +2903,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
2890
2903
|
const [view, setViewState] = useState6(initialView ?? (state.attention.length ? "list" : messengerViewMemory.get(memoryKey) ?? (state.attached || state.transcript.length ? "chat" : "list")));
|
|
2891
2904
|
const [opening, setOpening] = useState6(null);
|
|
2892
2905
|
const [newNavigation, setNewNavigation] = useState6(null);
|
|
2906
|
+
const [chatNavigation, setChatNavigation] = useState6(null);
|
|
2893
2907
|
const [listFocus, setListFocus] = useState6(null);
|
|
2894
2908
|
const lastNavigation = useRef7(null);
|
|
2895
2909
|
const setView = (next) => {
|
|
@@ -2902,17 +2916,21 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
2902
2916
|
lastNavigation.current = navigation.id;
|
|
2903
2917
|
if (navigation.view === "list") {
|
|
2904
2918
|
setOpening(null);
|
|
2919
|
+
setChatNavigation(null);
|
|
2905
2920
|
setView("list");
|
|
2906
2921
|
return;
|
|
2907
2922
|
}
|
|
2908
2923
|
if (navigation.view === "new") {
|
|
2909
2924
|
setListFocus("@new");
|
|
2925
|
+
setChatNavigation(null);
|
|
2910
2926
|
setNewNavigation(navigation);
|
|
2911
2927
|
setView("new");
|
|
2912
2928
|
return;
|
|
2913
2929
|
}
|
|
2914
2930
|
if (navigation.view === "chat" && typeof navigation.sessionKey === "string" && navigation.sessionKey) {
|
|
2915
2931
|
setListFocus(navigation.sessionKey);
|
|
2932
|
+
setNewNavigation(null);
|
|
2933
|
+
setChatNavigation(navigation);
|
|
2916
2934
|
if (state.attached?.key === navigation.sessionKey) {
|
|
2917
2935
|
setOpening(null);
|
|
2918
2936
|
setView("chat");
|
|
@@ -2934,6 +2952,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
2934
2952
|
}, [opening, state.attachError?.key, state.attached?.key, state.error, state.operation]);
|
|
2935
2953
|
const open = (row) => {
|
|
2936
2954
|
setListFocus(row.key);
|
|
2955
|
+
setChatNavigation(null);
|
|
2937
2956
|
setOpening(row);
|
|
2938
2957
|
adapter.onIntent({ action: "attach", key: row.key });
|
|
2939
2958
|
};
|
|
@@ -2943,6 +2962,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
2943
2962
|
return /* @__PURE__ */ jsxs8("main", { className: `scui-root ${className}`, "data-view": view, "data-mode": state.mode, "aria-label": "Supercode messenger", children: [
|
|
2944
2963
|
view === "list" ? /* @__PURE__ */ jsx9(SessionList, { state, adapter, focusKey: listFocus, onOpen: open, onNew: () => {
|
|
2945
2964
|
setListFocus("@new");
|
|
2965
|
+
setChatNavigation(null);
|
|
2946
2966
|
setNewNavigation(null);
|
|
2947
2967
|
setView("new");
|
|
2948
2968
|
}, onClose: adapter.onClose ? close : void 0, components, labels: copy, memoryKey, slots, headerActions: HeaderActions }) : null,
|
|
@@ -2952,9 +2972,10 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
|
|
|
2952
2972
|
setView("list");
|
|
2953
2973
|
}, onNew: () => {
|
|
2954
2974
|
setListFocus("@new");
|
|
2975
|
+
setChatNavigation(null);
|
|
2955
2976
|
setNewNavigation(null);
|
|
2956
2977
|
setView("new");
|
|
2957
|
-
}, onClose: adapter.onClose ? close : void 0, components, slots, labels: copy, contextCandidates }) : null,
|
|
2978
|
+
}, onClose: adapter.onClose ? close : void 0, components, slots, labels: copy, contextCandidates, navigation: chatNavigation?.sessionKey === state.attached?.key ? chatNavigation : null }) : null,
|
|
2958
2979
|
opening ? /* @__PURE__ */ jsxs8("div", { className: "scui-opening", role: "status", "aria-busy": "true", children: [
|
|
2959
2980
|
/* @__PURE__ */ jsx9(HarnessLogo, { id: opening.harness, size: 34 }),
|
|
2960
2981
|
/* @__PURE__ */ jsxs8("span", { children: [
|
package/react/sessions.mjs
CHANGED
|
@@ -365,6 +365,7 @@ function SessionList({ state, adapter, onOpen, onNew, onClose, components = {},
|
|
|
365
365
|
const rowScroller = useRef4(null);
|
|
366
366
|
const rows = filterSessions(state.sessions, query);
|
|
367
367
|
const Row = components.SessionRow ?? SessionRow;
|
|
368
|
+
const ListHeader = slots.listHeader;
|
|
368
369
|
const BeforeSessions = slots.beforeSessions;
|
|
369
370
|
const AfterSessions = slots.afterSessions;
|
|
370
371
|
useLayoutEffect2(() => {
|
|
@@ -391,7 +392,7 @@ function SessionList({ state, adapter, onOpen, onNew, onClose, components = {},
|
|
|
391
392
|
}
|
|
392
393
|
};
|
|
393
394
|
return /* @__PURE__ */ jsxs5("section", { className: "scui-list", ref: root, children: [
|
|
394
|
-
/* @__PURE__ */ jsxs5("header", { className: "scui-head", children: [
|
|
395
|
+
ListHeader ? /* @__PURE__ */ jsx6(ListHeader, { state, adapter, value: { query, rows, onNew } }) : /* @__PURE__ */ jsxs5("header", { className: "scui-head", children: [
|
|
395
396
|
/* @__PURE__ */ jsxs5("span", { className: "scui-head-copy", children: [
|
|
396
397
|
/* @__PURE__ */ jsx6("strong", { children: labels.chats }),
|
|
397
398
|
/* @__PURE__ */ jsxs5("small", { children: [
|
package/sessions.mjs
CHANGED
|
@@ -365,6 +365,7 @@ function SessionList({ state, adapter, onOpen, onNew, onClose, components = {},
|
|
|
365
365
|
const rowScroller = useRef4(null);
|
|
366
366
|
const rows = filterSessions(state.sessions, query);
|
|
367
367
|
const Row = components.SessionRow ?? SessionRow;
|
|
368
|
+
const ListHeader = slots.listHeader;
|
|
368
369
|
const BeforeSessions = slots.beforeSessions;
|
|
369
370
|
const AfterSessions = slots.afterSessions;
|
|
370
371
|
useLayoutEffect2(() => {
|
|
@@ -391,7 +392,7 @@ function SessionList({ state, adapter, onOpen, onNew, onClose, components = {},
|
|
|
391
392
|
}
|
|
392
393
|
};
|
|
393
394
|
return /* @__PURE__ */ jsxs5("section", { className: "scui-list", ref: root, children: [
|
|
394
|
-
/* @__PURE__ */ jsxs5("header", { className: "scui-head", children: [
|
|
395
|
+
ListHeader ? /* @__PURE__ */ jsx6(ListHeader, { state, adapter, value: { query, rows, onNew } }) : /* @__PURE__ */ jsxs5("header", { className: "scui-head", children: [
|
|
395
396
|
/* @__PURE__ */ jsxs5("span", { className: "scui-head-copy", children: [
|
|
396
397
|
/* @__PURE__ */ jsx6("strong", { children: labels.chats }),
|
|
397
398
|
/* @__PURE__ */ jsxs5("small", { children: [
|