@volter-ai-dev/supercode-ui 0.1.38 → 0.1.39

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 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 a new one, while `onViewChange` observes user navigation. Context candidates use the exact
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
@@ -2627,7 +2627,7 @@ function ChatHeader({ state, adapter, pendingStatus, actionPending, onBack, onNe
2627
2627
  onClose ? /* @__PURE__ */ jsx10("button", { type: "button", "aria-label": "Close", onClick: onClose, children: /* @__PURE__ */ jsx10(UiIcon, { name: "close", size: 18 }) }) : null
2628
2628
  ] });
2629
2629
  }
2630
- function Chat({ state, adapter, onBack, onNew, onClose, components, slots, labels, contextCandidates }) {
2630
+ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, labels, contextCandidates, navigation }) {
2631
2631
  const Header = slots.header;
2632
2632
  const HeaderActions = slots.headerActions;
2633
2633
  const memoryKey = state.attached?.key || `${state.harness}:${state.workspace}`;
@@ -2637,6 +2637,7 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
2637
2637
  const [settings, setSettings] = useState6(null);
2638
2638
  const restoreSequence = useRef7(0);
2639
2639
  const actionSequence = useRef7(0);
2640
+ const lastNavigation = useRef7(null);
2640
2641
  const acknowledged = useRef7(/* @__PURE__ */ new Set());
2641
2642
  const setPending = (update) => setPendingState((current) => {
2642
2643
  const next = typeof update === "function" ? update(current) : update;
@@ -2649,6 +2650,17 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
2649
2650
  setPendingAction(null);
2650
2651
  setRestoreDraft(null);
2651
2652
  }, [memoryKey]);
2653
+ useEffect8(() => {
2654
+ if (!navigation || navigation.id === lastNavigation.current) return;
2655
+ lastNavigation.current = navigation.id;
2656
+ if (navigation.draft === void 0 && !navigation.context?.length && !navigation.images?.length) return;
2657
+ setRestoreDraft({
2658
+ id: `host:${String(navigation.id)}`,
2659
+ text: navigation.draft ?? "",
2660
+ context: navigation.context,
2661
+ images: navigation.images
2662
+ });
2663
+ }, [navigation]);
2652
2664
  useEffect8(() => {
2653
2665
  if (!pending) return;
2654
2666
  if (state.transcript.some((entry) => entry.role === "user" && entry.text.trim() === pending.text.trim() && !pending.baselineIds.includes(entry.id))) {
@@ -2973,6 +2985,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
2973
2985
  const [view, setViewState] = useState6(initialView ?? (state.attention.length ? "list" : messengerViewMemory.get(memoryKey) ?? (state.attached || state.transcript.length ? "chat" : "list")));
2974
2986
  const [opening, setOpening] = useState6(null);
2975
2987
  const [newNavigation, setNewNavigation] = useState6(null);
2988
+ const [chatNavigation, setChatNavigation] = useState6(null);
2976
2989
  const [listFocus, setListFocus] = useState6(null);
2977
2990
  const lastNavigation = useRef7(null);
2978
2991
  const setView = (next) => {
@@ -2985,17 +2998,21 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
2985
2998
  lastNavigation.current = navigation.id;
2986
2999
  if (navigation.view === "list") {
2987
3000
  setOpening(null);
3001
+ setChatNavigation(null);
2988
3002
  setView("list");
2989
3003
  return;
2990
3004
  }
2991
3005
  if (navigation.view === "new") {
2992
3006
  setListFocus("@new");
3007
+ setChatNavigation(null);
2993
3008
  setNewNavigation(navigation);
2994
3009
  setView("new");
2995
3010
  return;
2996
3011
  }
2997
3012
  if (navigation.view === "chat" && typeof navigation.sessionKey === "string" && navigation.sessionKey) {
2998
3013
  setListFocus(navigation.sessionKey);
3014
+ setNewNavigation(null);
3015
+ setChatNavigation(navigation);
2999
3016
  if (state.attached?.key === navigation.sessionKey) {
3000
3017
  setOpening(null);
3001
3018
  setView("chat");
@@ -3017,6 +3034,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
3017
3034
  }, [opening, state.attachError?.key, state.attached?.key, state.error, state.operation]);
3018
3035
  const open = (row) => {
3019
3036
  setListFocus(row.key);
3037
+ setChatNavigation(null);
3020
3038
  setOpening(row);
3021
3039
  adapter.onIntent({ action: "attach", key: row.key });
3022
3040
  };
@@ -3026,6 +3044,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
3026
3044
  return /* @__PURE__ */ jsxs9("main", { className: `scui-root ${className}`, "data-view": view, "data-mode": state.mode, "aria-label": "Supercode messenger", children: [
3027
3045
  view === "list" ? /* @__PURE__ */ jsx10(SessionList, { state, adapter, focusKey: listFocus, onOpen: open, onNew: () => {
3028
3046
  setListFocus("@new");
3047
+ setChatNavigation(null);
3029
3048
  setNewNavigation(null);
3030
3049
  setView("new");
3031
3050
  }, onClose: adapter.onClose ? close : void 0, components, labels: copy, memoryKey, slots, headerActions: HeaderActions }) : null,
@@ -3035,9 +3054,10 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
3035
3054
  setView("list");
3036
3055
  }, onNew: () => {
3037
3056
  setListFocus("@new");
3057
+ setChatNavigation(null);
3038
3058
  setNewNavigation(null);
3039
3059
  setView("new");
3040
- }, onClose: adapter.onClose ? close : void 0, components, slots, labels: copy, contextCandidates }) : null,
3060
+ }, onClose: adapter.onClose ? close : void 0, components, slots, labels: copy, contextCandidates, navigation: chatNavigation?.sessionKey === state.attached?.key ? chatNavigation : null }) : null,
3041
3061
  opening ? /* @__PURE__ */ jsxs9("div", { className: "scui-opening", role: "status", "aria-busy": "true", children: [
3042
3062
  /* @__PURE__ */ jsx10(HarnessLogo, { id: opening.harness, size: 34 }),
3043
3063
  /* @__PURE__ */ jsxs9("span", { children: [
package/embed.mjs CHANGED
@@ -2547,7 +2547,7 @@ function ChatHeader({ state, adapter, pendingStatus, actionPending, onBack, onNe
2547
2547
  onClose ? /* @__PURE__ */ jsx9("button", { type: "button", "aria-label": "Close", onClick: onClose, children: /* @__PURE__ */ jsx9(UiIcon, { name: "close", size: 18 }) }) : null
2548
2548
  ] });
2549
2549
  }
2550
- function Chat({ state, adapter, onBack, onNew, onClose, components, slots, labels, contextCandidates }) {
2550
+ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, labels, contextCandidates, navigation }) {
2551
2551
  const Header = slots.header;
2552
2552
  const HeaderActions = slots.headerActions;
2553
2553
  const memoryKey = state.attached?.key || `${state.harness}:${state.workspace}`;
@@ -2557,6 +2557,7 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
2557
2557
  const [settings, setSettings] = useState6(null);
2558
2558
  const restoreSequence = useRef7(0);
2559
2559
  const actionSequence = useRef7(0);
2560
+ const lastNavigation = useRef7(null);
2560
2561
  const acknowledged = useRef7(/* @__PURE__ */ new Set());
2561
2562
  const setPending = (update) => setPendingState((current) => {
2562
2563
  const next = typeof update === "function" ? update(current) : update;
@@ -2569,6 +2570,17 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
2569
2570
  setPendingAction(null);
2570
2571
  setRestoreDraft(null);
2571
2572
  }, [memoryKey]);
2573
+ useEffect8(() => {
2574
+ if (!navigation || navigation.id === lastNavigation.current) return;
2575
+ lastNavigation.current = navigation.id;
2576
+ if (navigation.draft === void 0 && !navigation.context?.length && !navigation.images?.length) return;
2577
+ setRestoreDraft({
2578
+ id: `host:${String(navigation.id)}`,
2579
+ text: navigation.draft ?? "",
2580
+ context: navigation.context,
2581
+ images: navigation.images
2582
+ });
2583
+ }, [navigation]);
2572
2584
  useEffect8(() => {
2573
2585
  if (!pending) return;
2574
2586
  if (state.transcript.some((entry) => entry.role === "user" && entry.text.trim() === pending.text.trim() && !pending.baselineIds.includes(entry.id))) {
@@ -2893,6 +2905,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
2893
2905
  const [view, setViewState] = useState6(initialView ?? (state.attention.length ? "list" : messengerViewMemory.get(memoryKey) ?? (state.attached || state.transcript.length ? "chat" : "list")));
2894
2906
  const [opening, setOpening] = useState6(null);
2895
2907
  const [newNavigation, setNewNavigation] = useState6(null);
2908
+ const [chatNavigation, setChatNavigation] = useState6(null);
2896
2909
  const [listFocus, setListFocus] = useState6(null);
2897
2910
  const lastNavigation = useRef7(null);
2898
2911
  const setView = (next) => {
@@ -2905,17 +2918,21 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
2905
2918
  lastNavigation.current = navigation.id;
2906
2919
  if (navigation.view === "list") {
2907
2920
  setOpening(null);
2921
+ setChatNavigation(null);
2908
2922
  setView("list");
2909
2923
  return;
2910
2924
  }
2911
2925
  if (navigation.view === "new") {
2912
2926
  setListFocus("@new");
2927
+ setChatNavigation(null);
2913
2928
  setNewNavigation(navigation);
2914
2929
  setView("new");
2915
2930
  return;
2916
2931
  }
2917
2932
  if (navigation.view === "chat" && typeof navigation.sessionKey === "string" && navigation.sessionKey) {
2918
2933
  setListFocus(navigation.sessionKey);
2934
+ setNewNavigation(null);
2935
+ setChatNavigation(navigation);
2919
2936
  if (state.attached?.key === navigation.sessionKey) {
2920
2937
  setOpening(null);
2921
2938
  setView("chat");
@@ -2937,6 +2954,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
2937
2954
  }, [opening, state.attachError?.key, state.attached?.key, state.error, state.operation]);
2938
2955
  const open = (row) => {
2939
2956
  setListFocus(row.key);
2957
+ setChatNavigation(null);
2940
2958
  setOpening(row);
2941
2959
  adapter.onIntent({ action: "attach", key: row.key });
2942
2960
  };
@@ -2946,6 +2964,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
2946
2964
  return /* @__PURE__ */ jsxs8("main", { className: `scui-root ${className}`, "data-view": view, "data-mode": state.mode, "aria-label": "Supercode messenger", children: [
2947
2965
  view === "list" ? /* @__PURE__ */ jsx9(SessionList, { state, adapter, focusKey: listFocus, onOpen: open, onNew: () => {
2948
2966
  setListFocus("@new");
2967
+ setChatNavigation(null);
2949
2968
  setNewNavigation(null);
2950
2969
  setView("new");
2951
2970
  }, onClose: adapter.onClose ? close : void 0, components, labels: copy, memoryKey, slots, headerActions: HeaderActions }) : null,
@@ -2955,9 +2974,10 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
2955
2974
  setView("list");
2956
2975
  }, onNew: () => {
2957
2976
  setListFocus("@new");
2977
+ setChatNavigation(null);
2958
2978
  setNewNavigation(null);
2959
2979
  setView("new");
2960
- }, onClose: adapter.onClose ? close : void 0, components, slots, labels: copy, contextCandidates }) : null,
2980
+ }, onClose: adapter.onClose ? close : void 0, components, slots, labels: copy, contextCandidates, navigation: chatNavigation?.sessionKey === state.attached?.key ? chatNavigation : null }) : null,
2961
2981
  opening ? /* @__PURE__ */ jsxs8("div", { className: "scui-opening", role: "status", "aria-busy": "true", children: [
2962
2982
  /* @__PURE__ */ jsx9(HarnessLogo, { id: opening.harness, size: 34 }),
2963
2983
  /* @__PURE__ */ jsxs8("span", { children: [
package/index.d.ts CHANGED
@@ -468,7 +468,7 @@ export interface MessengerSlots {
468
468
 
469
469
  export type MessengerNavigation =
470
470
  | { id: string | number; view: 'list' }
471
- | { id: string | number; view: 'chat'; sessionKey: string }
471
+ | { id: string | number; view: 'chat'; sessionKey: string; draft?: string; context?: TranscriptContext[]; images?: Array<TranscriptImage & { url: string }> }
472
472
  | { id: string | number; view: 'new'; harness?: HarnessId; draft?: string; context?: TranscriptContext[]; images?: Array<TranscriptImage & { url: string }> };
473
473
 
474
474
  export interface MessengerProps {
package/messenger.mjs CHANGED
@@ -2544,7 +2544,7 @@ function ChatHeader({ state, adapter, pendingStatus, actionPending, onBack, onNe
2544
2544
  onClose ? /* @__PURE__ */ jsx9("button", { type: "button", "aria-label": "Close", onClick: onClose, children: /* @__PURE__ */ jsx9(UiIcon, { name: "close", size: 18 }) }) : null
2545
2545
  ] });
2546
2546
  }
2547
- function Chat({ state, adapter, onBack, onNew, onClose, components, slots, labels, contextCandidates }) {
2547
+ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, labels, contextCandidates, navigation }) {
2548
2548
  const Header = slots.header;
2549
2549
  const HeaderActions = slots.headerActions;
2550
2550
  const memoryKey = state.attached?.key || `${state.harness}:${state.workspace}`;
@@ -2554,6 +2554,7 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
2554
2554
  const [settings, setSettings] = useState6(null);
2555
2555
  const restoreSequence = useRef7(0);
2556
2556
  const actionSequence = useRef7(0);
2557
+ const lastNavigation = useRef7(null);
2557
2558
  const acknowledged = useRef7(/* @__PURE__ */ new Set());
2558
2559
  const setPending = (update) => setPendingState((current) => {
2559
2560
  const next = typeof update === "function" ? update(current) : update;
@@ -2566,6 +2567,17 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
2566
2567
  setPendingAction(null);
2567
2568
  setRestoreDraft(null);
2568
2569
  }, [memoryKey]);
2570
+ useEffect8(() => {
2571
+ if (!navigation || navigation.id === lastNavigation.current) return;
2572
+ lastNavigation.current = navigation.id;
2573
+ if (navigation.draft === void 0 && !navigation.context?.length && !navigation.images?.length) return;
2574
+ setRestoreDraft({
2575
+ id: `host:${String(navigation.id)}`,
2576
+ text: navigation.draft ?? "",
2577
+ context: navigation.context,
2578
+ images: navigation.images
2579
+ });
2580
+ }, [navigation]);
2569
2581
  useEffect8(() => {
2570
2582
  if (!pending) return;
2571
2583
  if (state.transcript.some((entry) => entry.role === "user" && entry.text.trim() === pending.text.trim() && !pending.baselineIds.includes(entry.id))) {
@@ -2890,6 +2902,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
2890
2902
  const [view, setViewState] = useState6(initialView ?? (state.attention.length ? "list" : messengerViewMemory.get(memoryKey) ?? (state.attached || state.transcript.length ? "chat" : "list")));
2891
2903
  const [opening, setOpening] = useState6(null);
2892
2904
  const [newNavigation, setNewNavigation] = useState6(null);
2905
+ const [chatNavigation, setChatNavigation] = useState6(null);
2893
2906
  const [listFocus, setListFocus] = useState6(null);
2894
2907
  const lastNavigation = useRef7(null);
2895
2908
  const setView = (next) => {
@@ -2902,17 +2915,21 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
2902
2915
  lastNavigation.current = navigation.id;
2903
2916
  if (navigation.view === "list") {
2904
2917
  setOpening(null);
2918
+ setChatNavigation(null);
2905
2919
  setView("list");
2906
2920
  return;
2907
2921
  }
2908
2922
  if (navigation.view === "new") {
2909
2923
  setListFocus("@new");
2924
+ setChatNavigation(null);
2910
2925
  setNewNavigation(navigation);
2911
2926
  setView("new");
2912
2927
  return;
2913
2928
  }
2914
2929
  if (navigation.view === "chat" && typeof navigation.sessionKey === "string" && navigation.sessionKey) {
2915
2930
  setListFocus(navigation.sessionKey);
2931
+ setNewNavigation(null);
2932
+ setChatNavigation(navigation);
2916
2933
  if (state.attached?.key === navigation.sessionKey) {
2917
2934
  setOpening(null);
2918
2935
  setView("chat");
@@ -2934,6 +2951,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
2934
2951
  }, [opening, state.attachError?.key, state.attached?.key, state.error, state.operation]);
2935
2952
  const open = (row) => {
2936
2953
  setListFocus(row.key);
2954
+ setChatNavigation(null);
2937
2955
  setOpening(row);
2938
2956
  adapter.onIntent({ action: "attach", key: row.key });
2939
2957
  };
@@ -2943,6 +2961,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
2943
2961
  return /* @__PURE__ */ jsxs8("main", { className: `scui-root ${className}`, "data-view": view, "data-mode": state.mode, "aria-label": "Supercode messenger", children: [
2944
2962
  view === "list" ? /* @__PURE__ */ jsx9(SessionList, { state, adapter, focusKey: listFocus, onOpen: open, onNew: () => {
2945
2963
  setListFocus("@new");
2964
+ setChatNavigation(null);
2946
2965
  setNewNavigation(null);
2947
2966
  setView("new");
2948
2967
  }, onClose: adapter.onClose ? close : void 0, components, labels: copy, memoryKey, slots, headerActions: HeaderActions }) : null,
@@ -2952,9 +2971,10 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
2952
2971
  setView("list");
2953
2972
  }, onNew: () => {
2954
2973
  setListFocus("@new");
2974
+ setChatNavigation(null);
2955
2975
  setNewNavigation(null);
2956
2976
  setView("new");
2957
- }, onClose: adapter.onClose ? close : void 0, components, slots, labels: copy, contextCandidates }) : null,
2977
+ }, onClose: adapter.onClose ? close : void 0, components, slots, labels: copy, contextCandidates, navigation: chatNavigation?.sessionKey === state.attached?.key ? chatNavigation : null }) : null,
2958
2978
  opening ? /* @__PURE__ */ jsxs8("div", { className: "scui-opening", role: "status", "aria-busy": "true", children: [
2959
2979
  /* @__PURE__ */ jsx9(HarnessLogo, { id: opening.harness, size: 34 }),
2960
2980
  /* @__PURE__ */ jsxs8("span", { children: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter-ai-dev/supercode-ui",
3
- "version": "0.1.38",
3
+ "version": "0.1.39",
4
4
  "type": "module",
5
5
  "description": "Composable default UI kit for Supercode-powered coding-agent experiences",
6
6
  "exports": {
@@ -2627,7 +2627,7 @@ function ChatHeader({ state, adapter, pendingStatus, actionPending, onBack, onNe
2627
2627
  onClose ? /* @__PURE__ */ jsx10("button", { type: "button", "aria-label": "Close", onClick: onClose, children: /* @__PURE__ */ jsx10(UiIcon, { name: "close", size: 18 }) }) : null
2628
2628
  ] });
2629
2629
  }
2630
- function Chat({ state, adapter, onBack, onNew, onClose, components, slots, labels, contextCandidates }) {
2630
+ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, labels, contextCandidates, navigation }) {
2631
2631
  const Header = slots.header;
2632
2632
  const HeaderActions = slots.headerActions;
2633
2633
  const memoryKey = state.attached?.key || `${state.harness}:${state.workspace}`;
@@ -2637,6 +2637,7 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
2637
2637
  const [settings, setSettings] = useState6(null);
2638
2638
  const restoreSequence = useRef7(0);
2639
2639
  const actionSequence = useRef7(0);
2640
+ const lastNavigation = useRef7(null);
2640
2641
  const acknowledged = useRef7(/* @__PURE__ */ new Set());
2641
2642
  const setPending = (update) => setPendingState((current) => {
2642
2643
  const next = typeof update === "function" ? update(current) : update;
@@ -2649,6 +2650,17 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
2649
2650
  setPendingAction(null);
2650
2651
  setRestoreDraft(null);
2651
2652
  }, [memoryKey]);
2653
+ useEffect8(() => {
2654
+ if (!navigation || navigation.id === lastNavigation.current) return;
2655
+ lastNavigation.current = navigation.id;
2656
+ if (navigation.draft === void 0 && !navigation.context?.length && !navigation.images?.length) return;
2657
+ setRestoreDraft({
2658
+ id: `host:${String(navigation.id)}`,
2659
+ text: navigation.draft ?? "",
2660
+ context: navigation.context,
2661
+ images: navigation.images
2662
+ });
2663
+ }, [navigation]);
2652
2664
  useEffect8(() => {
2653
2665
  if (!pending) return;
2654
2666
  if (state.transcript.some((entry) => entry.role === "user" && entry.text.trim() === pending.text.trim() && !pending.baselineIds.includes(entry.id))) {
@@ -2973,6 +2985,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
2973
2985
  const [view, setViewState] = useState6(initialView ?? (state.attention.length ? "list" : messengerViewMemory.get(memoryKey) ?? (state.attached || state.transcript.length ? "chat" : "list")));
2974
2986
  const [opening, setOpening] = useState6(null);
2975
2987
  const [newNavigation, setNewNavigation] = useState6(null);
2988
+ const [chatNavigation, setChatNavigation] = useState6(null);
2976
2989
  const [listFocus, setListFocus] = useState6(null);
2977
2990
  const lastNavigation = useRef7(null);
2978
2991
  const setView = (next) => {
@@ -2985,17 +2998,21 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
2985
2998
  lastNavigation.current = navigation.id;
2986
2999
  if (navigation.view === "list") {
2987
3000
  setOpening(null);
3001
+ setChatNavigation(null);
2988
3002
  setView("list");
2989
3003
  return;
2990
3004
  }
2991
3005
  if (navigation.view === "new") {
2992
3006
  setListFocus("@new");
3007
+ setChatNavigation(null);
2993
3008
  setNewNavigation(navigation);
2994
3009
  setView("new");
2995
3010
  return;
2996
3011
  }
2997
3012
  if (navigation.view === "chat" && typeof navigation.sessionKey === "string" && navigation.sessionKey) {
2998
3013
  setListFocus(navigation.sessionKey);
3014
+ setNewNavigation(null);
3015
+ setChatNavigation(navigation);
2999
3016
  if (state.attached?.key === navigation.sessionKey) {
3000
3017
  setOpening(null);
3001
3018
  setView("chat");
@@ -3017,6 +3034,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
3017
3034
  }, [opening, state.attachError?.key, state.attached?.key, state.error, state.operation]);
3018
3035
  const open = (row) => {
3019
3036
  setListFocus(row.key);
3037
+ setChatNavigation(null);
3020
3038
  setOpening(row);
3021
3039
  adapter.onIntent({ action: "attach", key: row.key });
3022
3040
  };
@@ -3026,6 +3044,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
3026
3044
  return /* @__PURE__ */ jsxs9("main", { className: `scui-root ${className}`, "data-view": view, "data-mode": state.mode, "aria-label": "Supercode messenger", children: [
3027
3045
  view === "list" ? /* @__PURE__ */ jsx10(SessionList, { state, adapter, focusKey: listFocus, onOpen: open, onNew: () => {
3028
3046
  setListFocus("@new");
3047
+ setChatNavigation(null);
3029
3048
  setNewNavigation(null);
3030
3049
  setView("new");
3031
3050
  }, onClose: adapter.onClose ? close : void 0, components, labels: copy, memoryKey, slots, headerActions: HeaderActions }) : null,
@@ -3035,9 +3054,10 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
3035
3054
  setView("list");
3036
3055
  }, onNew: () => {
3037
3056
  setListFocus("@new");
3057
+ setChatNavigation(null);
3038
3058
  setNewNavigation(null);
3039
3059
  setView("new");
3040
- }, onClose: adapter.onClose ? close : void 0, components, slots, labels: copy, contextCandidates }) : null,
3060
+ }, onClose: adapter.onClose ? close : void 0, components, slots, labels: copy, contextCandidates, navigation: chatNavigation?.sessionKey === state.attached?.key ? chatNavigation : null }) : null,
3041
3061
  opening ? /* @__PURE__ */ jsxs9("div", { className: "scui-opening", role: "status", "aria-busy": "true", children: [
3042
3062
  /* @__PURE__ */ jsx10(HarnessLogo, { id: opening.harness, size: 34 }),
3043
3063
  /* @__PURE__ */ jsxs9("span", { children: [
@@ -2544,7 +2544,7 @@ function ChatHeader({ state, adapter, pendingStatus, actionPending, onBack, onNe
2544
2544
  onClose ? /* @__PURE__ */ jsx9("button", { type: "button", "aria-label": "Close", onClick: onClose, children: /* @__PURE__ */ jsx9(UiIcon, { name: "close", size: 18 }) }) : null
2545
2545
  ] });
2546
2546
  }
2547
- function Chat({ state, adapter, onBack, onNew, onClose, components, slots, labels, contextCandidates }) {
2547
+ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, labels, contextCandidates, navigation }) {
2548
2548
  const Header = slots.header;
2549
2549
  const HeaderActions = slots.headerActions;
2550
2550
  const memoryKey = state.attached?.key || `${state.harness}:${state.workspace}`;
@@ -2554,6 +2554,7 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
2554
2554
  const [settings, setSettings] = useState6(null);
2555
2555
  const restoreSequence = useRef7(0);
2556
2556
  const actionSequence = useRef7(0);
2557
+ const lastNavigation = useRef7(null);
2557
2558
  const acknowledged = useRef7(/* @__PURE__ */ new Set());
2558
2559
  const setPending = (update) => setPendingState((current) => {
2559
2560
  const next = typeof update === "function" ? update(current) : update;
@@ -2566,6 +2567,17 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
2566
2567
  setPendingAction(null);
2567
2568
  setRestoreDraft(null);
2568
2569
  }, [memoryKey]);
2570
+ useEffect8(() => {
2571
+ if (!navigation || navigation.id === lastNavigation.current) return;
2572
+ lastNavigation.current = navigation.id;
2573
+ if (navigation.draft === void 0 && !navigation.context?.length && !navigation.images?.length) return;
2574
+ setRestoreDraft({
2575
+ id: `host:${String(navigation.id)}`,
2576
+ text: navigation.draft ?? "",
2577
+ context: navigation.context,
2578
+ images: navigation.images
2579
+ });
2580
+ }, [navigation]);
2569
2581
  useEffect8(() => {
2570
2582
  if (!pending) return;
2571
2583
  if (state.transcript.some((entry) => entry.role === "user" && entry.text.trim() === pending.text.trim() && !pending.baselineIds.includes(entry.id))) {
@@ -2890,6 +2902,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
2890
2902
  const [view, setViewState] = useState6(initialView ?? (state.attention.length ? "list" : messengerViewMemory.get(memoryKey) ?? (state.attached || state.transcript.length ? "chat" : "list")));
2891
2903
  const [opening, setOpening] = useState6(null);
2892
2904
  const [newNavigation, setNewNavigation] = useState6(null);
2905
+ const [chatNavigation, setChatNavigation] = useState6(null);
2893
2906
  const [listFocus, setListFocus] = useState6(null);
2894
2907
  const lastNavigation = useRef7(null);
2895
2908
  const setView = (next) => {
@@ -2902,17 +2915,21 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
2902
2915
  lastNavigation.current = navigation.id;
2903
2916
  if (navigation.view === "list") {
2904
2917
  setOpening(null);
2918
+ setChatNavigation(null);
2905
2919
  setView("list");
2906
2920
  return;
2907
2921
  }
2908
2922
  if (navigation.view === "new") {
2909
2923
  setListFocus("@new");
2924
+ setChatNavigation(null);
2910
2925
  setNewNavigation(navigation);
2911
2926
  setView("new");
2912
2927
  return;
2913
2928
  }
2914
2929
  if (navigation.view === "chat" && typeof navigation.sessionKey === "string" && navigation.sessionKey) {
2915
2930
  setListFocus(navigation.sessionKey);
2931
+ setNewNavigation(null);
2932
+ setChatNavigation(navigation);
2916
2933
  if (state.attached?.key === navigation.sessionKey) {
2917
2934
  setOpening(null);
2918
2935
  setView("chat");
@@ -2934,6 +2951,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
2934
2951
  }, [opening, state.attachError?.key, state.attached?.key, state.error, state.operation]);
2935
2952
  const open = (row) => {
2936
2953
  setListFocus(row.key);
2954
+ setChatNavigation(null);
2937
2955
  setOpening(row);
2938
2956
  adapter.onIntent({ action: "attach", key: row.key });
2939
2957
  };
@@ -2943,6 +2961,7 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
2943
2961
  return /* @__PURE__ */ jsxs8("main", { className: `scui-root ${className}`, "data-view": view, "data-mode": state.mode, "aria-label": "Supercode messenger", children: [
2944
2962
  view === "list" ? /* @__PURE__ */ jsx9(SessionList, { state, adapter, focusKey: listFocus, onOpen: open, onNew: () => {
2945
2963
  setListFocus("@new");
2964
+ setChatNavigation(null);
2946
2965
  setNewNavigation(null);
2947
2966
  setView("new");
2948
2967
  }, onClose: adapter.onClose ? close : void 0, components, labels: copy, memoryKey, slots, headerActions: HeaderActions }) : null,
@@ -2952,9 +2971,10 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
2952
2971
  setView("list");
2953
2972
  }, onNew: () => {
2954
2973
  setListFocus("@new");
2974
+ setChatNavigation(null);
2955
2975
  setNewNavigation(null);
2956
2976
  setView("new");
2957
- }, onClose: adapter.onClose ? close : void 0, components, slots, labels: copy, contextCandidates }) : null,
2977
+ }, onClose: adapter.onClose ? close : void 0, components, slots, labels: copy, contextCandidates, navigation: chatNavigation?.sessionKey === state.attached?.key ? chatNavigation : null }) : null,
2958
2978
  opening ? /* @__PURE__ */ jsxs8("div", { className: "scui-opening", role: "status", "aria-busy": "true", children: [
2959
2979
  /* @__PURE__ */ jsx9(HarnessLogo, { id: opening.harness, size: 34 }),
2960
2980
  /* @__PURE__ */ jsxs8("span", { children: [