@nextclaw/ui 0.12.7 → 0.12.9

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.
Files changed (171) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/dist/assets/ChannelsList-Ita2Zm1_.js +8 -0
  3. package/dist/assets/{DocBrowser-Cse_F8Nn.js → DocBrowser-6ReNjvzF.js} +1 -1
  4. package/dist/assets/DocBrowser-BNwbPHf4.js +1 -0
  5. package/dist/assets/{DocBrowserContext-Bai1WU2H.js → DocBrowserContext-B6SpA7Qs.js} +1 -1
  6. package/dist/assets/{LogoBadge-BdxMPc9v.js → LogoBadge-ByNLYg65.js} +1 -1
  7. package/dist/assets/MarketplacePage-CjX2MWww.js +1 -0
  8. package/dist/assets/{MarketplacePage-BbpAkllU.js → MarketplacePage-D0sDlYX4.js} +1 -1
  9. package/dist/assets/McpMarketplacePage-BGKJm1sJ.js +40 -0
  10. package/dist/assets/{ModelConfig-3GLqQ5GY.js → ModelConfig-BzZenCH-.js} +1 -1
  11. package/dist/assets/{ProviderScopedModelInput-BYNouw-i.js → ProviderScopedModelInput-Da7khnBA.js} +1 -1
  12. package/dist/assets/{ProvidersList-BR1gJ4Dm.js → ProvidersList-BbVzRxjY.js} +1 -1
  13. package/dist/assets/RemoteAccessPage-BaDH_X1Q.js +1 -0
  14. package/dist/assets/RuntimeConfig-F_XKGgLm.js +1 -0
  15. package/dist/assets/{SearchConfig-DTeJvp8m.js → SearchConfig-BGkzXQP-.js} +1 -1
  16. package/dist/assets/{SecretsConfig-CCYO6NcV.js → SecretsConfig-D281Rotl.js} +2 -2
  17. package/dist/assets/{SessionsConfig-Du39vDgt.js → SessionsConfig-ChHQ7M5c.js} +2 -2
  18. package/dist/assets/{app-query-client-Dr5d-K8d.js → app-query-client-VnFElj4E.js} +1 -1
  19. package/dist/assets/{book-open-Da4OEPqB.js → book-open-BdcxxoQu.js} +1 -1
  20. package/dist/assets/chat-page-Doe0yTtB.js +58 -0
  21. package/dist/assets/chat-session-display-cw78aiI_.js +1 -0
  22. package/dist/assets/{chunk-JZWAC4HX-CoFVxHXV.js → chunk-JZWAC4HX-DK5HPmIK.js} +1 -1
  23. package/dist/assets/{client-CSk58DcF.js → client-_i4MU2bB.js} +1 -1
  24. package/dist/assets/{config-D8KzikVB.js → config-DtIQwrHF.js} +1 -1
  25. package/dist/assets/{createLucideIcon-83gaZMtv.js → createLucideIcon-BSeTgkZW.js} +1 -1
  26. package/dist/assets/desktop-update-config-Dpcf4BKG.js +1 -0
  27. package/dist/assets/{dist-toEYs-MZ.js → dist-6TrrnPCR.js} +1 -1
  28. package/dist/assets/{dist-aTmhMDVh.js → dist-ccBFUi-o.js} +1 -1
  29. package/dist/assets/download-BhDxnyvU.js +1 -0
  30. package/dist/assets/{external-link-QQ0TC6X4.js → external-link-BgErLCNT.js} +1 -1
  31. package/dist/assets/{hash-DaFBEkmi.js → hash-Bl7dr_UG.js} +1 -1
  32. package/dist/assets/i18n-eDHeDY0n.js +1 -0
  33. package/dist/assets/index-CF9xve0E.js +6 -0
  34. package/dist/assets/index-FgA52VBt.css +1 -0
  35. package/dist/assets/{infiniteQueryBehavior-BmHX_ayZ.js → infiniteQueryBehavior-ZDS92Qpp.js} +1 -1
  36. package/dist/assets/loader-circle-ACM1s51e.js +1 -0
  37. package/dist/assets/{logos-Dzlz30M3.js → logos-x89HbrZ4.js} +1 -1
  38. package/dist/assets/{page-layout-D2eRufRQ.js → page-layout-vZnghcFy.js} +1 -1
  39. package/dist/assets/play-CFUwCA2E.js +1 -0
  40. package/dist/assets/plus-rYsv72JG.js +1 -0
  41. package/dist/assets/{popover-BSXxm5bj.js → popover-Bg1VoTZ6.js} +1 -1
  42. package/dist/assets/{refresh-ccw-B3zMtN-_.js → refresh-ccw-DT98i__E.js} +1 -1
  43. package/dist/assets/{refresh-cw-DlZkIHnJ.js → refresh-cw-C47QSEwg.js} +1 -1
  44. package/dist/assets/rotate-cw-JtFzpNn6.js +1 -0
  45. package/dist/assets/{save-Us9fg4Sj.js → save-3S6-H3Xw.js} +1 -1
  46. package/dist/assets/search-3kFR_zh9.js +1 -0
  47. package/dist/assets/{security-config-BGWYwxNr.js → security-config-BWaiARNk.js} +1 -1
  48. package/dist/assets/{select-DLYqySQK.js → select-DJ2MUjBB.js} +1 -1
  49. package/dist/assets/skeleton-ByQepn0M.js +1 -0
  50. package/dist/assets/{status-dot-DGayudyB.js → status-dot-vbanNPFU.js} +1 -1
  51. package/dist/assets/{switch-Dz2ScsKx.js → switch-BsLtHOH-.js} +1 -1
  52. package/dist/assets/{tabs-custom-CdKyjiGk.js → tabs-custom-D3HYMt6k.js} +1 -1
  53. package/dist/assets/{trash-2-Db-mZOZs.js → trash-2-G48scll7.js} +1 -1
  54. package/dist/assets/{use-infinite-scroll-loader-DBJX5hj0.js → use-infinite-scroll-loader-DkNhD-42.js} +1 -1
  55. package/dist/assets/{useConfirmDialog-DL0a-oGC.js → useConfirmDialog-BkvTN-vd.js} +1 -1
  56. package/dist/assets/{useMutation-BdZm-9PL.js → useMutation-CBWjE2uj.js} +1 -1
  57. package/dist/assets/x-ByDbItbq.js +1 -0
  58. package/dist/index.html +95 -21
  59. package/dist/manifest.webmanifest +30 -0
  60. package/dist/offline.html +102 -0
  61. package/dist/pwa-192.png +0 -0
  62. package/dist/pwa-512.png +0 -0
  63. package/dist/sw.js +80 -0
  64. package/index.html +73 -1
  65. package/package.json +6 -6
  66. package/public/manifest.webmanifest +30 -0
  67. package/public/offline.html +102 -0
  68. package/public/pwa-192.png +0 -0
  69. package/public/pwa-512.png +0 -0
  70. package/public/sw.js +80 -0
  71. package/src/api/runtime-control.ts +34 -0
  72. package/src/api/runtime-control.types.ts +58 -0
  73. package/src/api/server-path.ts +27 -4
  74. package/src/api/types.ts +30 -10
  75. package/src/{App.test.tsx → app.test.tsx} +1 -1
  76. package/src/{App.tsx → app.tsx} +10 -1
  77. package/src/components/chat/ChatSidebar.test.tsx +79 -8
  78. package/src/components/chat/ChatSidebar.tsx +43 -26
  79. package/src/components/chat/adapters/chat-message.summary-truncation.test.ts +66 -0
  80. package/src/components/chat/adapters/file-operation/card.ts +9 -0
  81. package/src/components/chat/adapters/file-operation/diff.ts +14 -0
  82. package/src/components/chat/{ChatConversationPanel.test.tsx → chat-conversation-panel.test.tsx} +118 -155
  83. package/src/components/chat/chat-conversation-panel.tsx +412 -0
  84. package/src/components/chat/chat-page-runtime.test.ts +1 -1
  85. package/src/components/chat/chat-page-shell.tsx +1 -1
  86. package/src/components/chat/{ChatPage.tsx → chat-page.tsx} +1 -1
  87. package/src/components/chat/chat-session-workspace-file-preview.test.tsx +91 -0
  88. package/src/components/chat/chat-session-workspace-file-preview.tsx +307 -0
  89. package/src/components/chat/chat-session-workspace-panel-nav.tsx +197 -0
  90. package/src/components/chat/chat-session-workspace-panel.tsx +318 -0
  91. package/src/components/chat/chat-sidebar-session-item.tsx +32 -2
  92. package/src/components/chat/containers/chat-message-list.container.test.tsx +49 -0
  93. package/src/components/chat/containers/chat-message-list.container.tsx +4 -0
  94. package/src/components/chat/managers/chat-session-list.manager.test.ts +94 -31
  95. package/src/components/chat/managers/chat-session-list.manager.ts +86 -14
  96. package/src/components/chat/managers/chat-ui.manager.ts +2 -0
  97. package/src/components/chat/ncp/README.md +1 -1
  98. package/src/components/chat/ncp/ncp-chat-input.manager.ts +7 -1
  99. package/src/components/chat/ncp/ncp-chat-page-data.test.ts +1 -1
  100. package/src/components/chat/ncp/{NcpChatPage.tsx → ncp-chat-page.tsx} +7 -7
  101. package/src/components/chat/ncp/ncp-chat-thread.manager.ts +179 -41
  102. package/src/components/chat/ncp/ncp-session-adapter.test.ts +40 -2
  103. package/src/components/chat/ncp/ncp-session-adapter.ts +29 -0
  104. package/src/components/chat/ncp/page/ncp-chat-derived-state.ts +54 -11
  105. package/src/components/chat/ncp/session-conversation/use-ncp-child-session-tabs-view.ts +4 -0
  106. package/src/components/chat/ncp/tests/ncp-chat-input.manager.test.ts +99 -0
  107. package/src/components/chat/ncp/tests/ncp-chat-thread.manager.test.ts +189 -0
  108. package/src/components/chat/presenter/chat-presenter-context.tsx +13 -2
  109. package/src/components/chat/session-header/chat-session-header-actions.test.tsx +26 -0
  110. package/src/components/chat/session-header/chat-session-header-actions.tsx +19 -1
  111. package/src/components/chat/stores/chat-session-list.store.ts +25 -54
  112. package/src/components/chat/stores/chat-thread.store.ts +24 -0
  113. package/src/components/common/ProviderScopedModelInput.tsx +12 -2
  114. package/src/components/config/ModelConfig.test.tsx +108 -2
  115. package/src/components/config/RuntimeConfig.tsx +154 -7
  116. package/src/components/config/desktop-update-config.test.tsx +85 -0
  117. package/src/components/config/desktop-update-config.tsx +44 -3
  118. package/src/components/config/runtime-control-card.test.tsx +255 -0
  119. package/src/components/config/runtime-control-card.tsx +301 -0
  120. package/src/components/config/runtime-presence-card.test.tsx +154 -0
  121. package/src/components/config/runtime-presence-card.tsx +163 -0
  122. package/src/components/layout/AppLayout.tsx +1 -1
  123. package/src/components/providers/ThemeProvider.tsx +5 -0
  124. package/src/desktop/desktop-update.types.ts +25 -0
  125. package/src/desktop/managers/desktop-presence.manager.ts +91 -0
  126. package/src/desktop/managers/desktop-update.manager.ts +37 -1
  127. package/src/desktop/stores/desktop-presence.store.ts +18 -0
  128. package/src/desktop/stores/desktop-update.store.ts +7 -1
  129. package/src/hooks/server-path/use-server-path-read.ts +20 -0
  130. package/src/hooks/use-runtime-control.ts +24 -0
  131. package/src/lib/chat-message.ts +14 -3
  132. package/src/lib/desktop-update-labels.utils.ts +28 -2
  133. package/src/lib/i18n.chat.ts +12 -1
  134. package/src/lib/i18n.pwa.ts +62 -0
  135. package/src/lib/i18n.runtime-control.ts +120 -0
  136. package/src/lib/i18n.ts +4 -6
  137. package/src/main.tsx +1 -1
  138. package/src/pwa/components/pwa-install-entry.test.tsx +110 -0
  139. package/src/pwa/components/pwa-install-entry.tsx +205 -0
  140. package/src/pwa/managers/pwa-install.manager.test.ts +160 -0
  141. package/src/pwa/managers/pwa-install.manager.ts +232 -0
  142. package/src/pwa/managers/pwa-runtime.manager.ts +196 -0
  143. package/src/pwa/managers/pwa-shell-theme.manager.test.ts +30 -0
  144. package/src/pwa/managers/pwa-shell-theme.manager.ts +46 -0
  145. package/src/pwa/pwa-install-banner.storage.ts +55 -0
  146. package/src/pwa/pwa.types.ts +22 -0
  147. package/src/pwa/register-pwa.ts +14 -0
  148. package/src/pwa/stores/pwa.store.ts +17 -0
  149. package/src/runtime-control/runtime-control.manager.ts +118 -0
  150. package/src/vite-env.d.ts +9 -0
  151. package/dist/assets/ChannelsList-D8p4OlM6.js +0 -8
  152. package/dist/assets/ChatPage-A45t1Rmf.js +0 -58
  153. package/dist/assets/DocBrowser-B2MpsnU9.js +0 -1
  154. package/dist/assets/MarketplacePage-BNZ3Jx5d.js +0 -1
  155. package/dist/assets/McpMarketplacePage-CxPFOgxv.js +0 -40
  156. package/dist/assets/RemoteAccessPage-DyYVWsyK.js +0 -1
  157. package/dist/assets/RuntimeConfig-ChdfK4Y_.js +0 -1
  158. package/dist/assets/chat-session-display-CAlPrnlV.js +0 -1
  159. package/dist/assets/desktop-update-config-CfoVwf-w.js +0 -1
  160. package/dist/assets/i18n-C3jb83S6.js +0 -1
  161. package/dist/assets/index-CE4N7ItL.css +0 -1
  162. package/dist/assets/index-riX7Sg0_.js +0 -6
  163. package/dist/assets/loader-circle-BjMg63eu.js +0 -1
  164. package/dist/assets/plus-CIXME2pD.js +0 -1
  165. package/dist/assets/search-B_Qr0f6C.js +0 -1
  166. package/dist/assets/skeleton-CYQJazv6.js +0 -1
  167. package/dist/assets/x-B8Tho_xC.js +0 -1
  168. package/src/components/chat/ChatConversationPanel.tsx +0 -256
  169. package/src/components/chat/chat-child-session-panel.tsx +0 -262
  170. /package/dist/assets/{config-hints-GSUMvmSo.js → config-hints-BhTmc9P1.js} +0 -0
  171. /package/dist/assets/{config-layout-CgBMG7OL.js → config-layout-CHs0mAaR.js} +0 -0
@@ -1,262 +0,0 @@
1
- import { useEffect, useRef } from "react";
2
- import { ArrowLeft, Loader2, X } from "lucide-react";
3
- import { useStickyBottomScroll } from "@nextclaw/agent-chat-ui";
4
- import { ChatMessageListContainer } from "@/components/chat/containers/chat-message-list.container";
5
- import {
6
- useNcpChildSessionTabsView,
7
- type ResolvedChildSessionTab,
8
- } from "@/components/chat/ncp/session-conversation/use-ncp-child-session-tabs-view";
9
- import { useNcpSessionConversation } from "@/components/chat/ncp/session-conversation/use-ncp-session-conversation";
10
- import {
11
- shouldShowUnreadSessionIndicator,
12
- useChatSessionListStore,
13
- } from "@/components/chat/stores/chat-session-list.store";
14
- import { usePresenter } from "@/components/chat/presenter/chat-presenter-context";
15
- import type { ChatChildSessionTab } from "@/components/chat/stores/chat-thread.store";
16
- import { AgentIdentityAvatar } from "@/components/common/agent-identity";
17
- import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
18
- import { t } from "@/lib/i18n";
19
- import { cn } from "@/lib/utils";
20
- import type { ChatToolActionViewModel } from "@nextclaw/agent-chat-ui";
21
-
22
- type ChatChildSessionPanelProps = {
23
- tabs: readonly ChatChildSessionTab[];
24
- activeSessionKey: string;
25
- onSelectSession: (sessionKey: string) => void;
26
- onClose: () => void;
27
- onBackToParent: () => void;
28
- onToolAction?: (action: ChatToolActionViewModel) => void;
29
- };
30
-
31
- function ChildSessionPanelConversation({
32
- sessionKey,
33
- onToolAction,
34
- }: {
35
- sessionKey: string;
36
- onToolAction?: (action: ChatToolActionViewModel) => void;
37
- }) {
38
- const agent = useNcpSessionConversation(sessionKey);
39
- const messages = agent.visibleMessages;
40
- const scrollRef = useRef<HTMLDivElement>(null);
41
- const { onScroll } = useStickyBottomScroll({
42
- scrollRef,
43
- resetKey: sessionKey,
44
- isLoading: agent.isHydrating,
45
- hasContent: messages.length > 0,
46
- contentVersion: messages[messages.length - 1] ?? null,
47
- stickyThresholdPx: 20,
48
- });
49
-
50
- return (
51
- <div
52
- ref={scrollRef}
53
- onScroll={onScroll}
54
- className="h-full overflow-y-auto custom-scrollbar"
55
- >
56
- {agent.isHydrating ? (
57
- <div className="flex h-full items-center justify-center text-sm text-gray-500">
58
- <Loader2 className="mr-2 h-4 w-4 animate-spin" />
59
- {t("chatChildSessionLoading")}
60
- </div>
61
- ) : agent.hydrateError ? (
62
- <div className="px-4 py-5 text-sm text-rose-600">
63
- {agent.hydrateError.message}
64
- </div>
65
- ) : messages.length === 0 && !agent.isRunning ? (
66
- <div className="px-4 py-5 text-sm text-gray-500">
67
- {t("chatChildSessionEmpty")}
68
- </div>
69
- ) : (
70
- <div className="px-4 py-5">
71
- <ChatMessageListContainer
72
- messages={messages}
73
- isSending={agent.isRunning}
74
- onToolAction={onToolAction}
75
- />
76
- </div>
77
- )}
78
- </div>
79
- );
80
- }
81
-
82
- function ChildSessionPanelMetaChip({ value }: { value: string }) {
83
- return (
84
- <span className="inline-flex max-w-full items-center rounded-full border border-gray-200/80 bg-gray-50/90 px-2.5 py-1 text-[11px] font-medium text-gray-600">
85
- <span className="truncate">{value}</span>
86
- </span>
87
- );
88
- }
89
-
90
- function ChildSessionPanelMetaStrip({ tab }: { tab: ResolvedChildSessionTab }) {
91
- const metaItems = [
92
- tab.sessionTypeLabel,
93
- tab.preferredModel,
94
- tab.projectName,
95
- ].filter((value): value is string => Boolean(value?.trim()));
96
-
97
- if (metaItems.length === 0 && !tab.projectRoot) {
98
- return null;
99
- }
100
-
101
- return (
102
- <div className="mt-3 space-y-2">
103
- {metaItems.length > 0 ? (
104
- <div className="flex flex-wrap gap-1.5">
105
- {metaItems.map((item) => (
106
- <ChildSessionPanelMetaChip key={item} value={item} />
107
- ))}
108
- </div>
109
- ) : null}
110
- {tab.projectRoot ? (
111
- <div
112
- title={tab.projectRoot}
113
- className="truncate rounded-xl border border-gray-200/70 bg-gray-50/80 px-2.5 py-2 font-mono text-[11px] text-gray-500"
114
- >
115
- {tab.projectRoot}
116
- </div>
117
- ) : null}
118
- </div>
119
- );
120
- }
121
-
122
- export function ChatChildSessionPanel({
123
- tabs,
124
- activeSessionKey,
125
- onSelectSession,
126
- onClose,
127
- onBackToParent,
128
- onToolAction,
129
- }: ChatChildSessionPanelProps) {
130
- const presenter = usePresenter();
131
- const resolvedTabs = useNcpChildSessionTabsView(tabs);
132
- const readUpdatedAtBySessionKey = useChatSessionListStore(
133
- (state) => state.readUpdatedAtBySessionKey,
134
- );
135
- const activeTab =
136
- resolvedTabs.find((tab) => tab.sessionKey === activeSessionKey) ??
137
- resolvedTabs[0] ??
138
- null;
139
- const activeTabSessionKey = activeTab?.sessionKey ?? null;
140
- const activeTabUpdatedAt = activeTab?.updatedAt?.trim() ?? null;
141
- const hasParentSession = resolvedTabs.some((tab) =>
142
- Boolean(tab.parentSessionKey),
143
- );
144
- const shouldShowTabs = resolvedTabs.length > 1;
145
-
146
- useEffect(() => {
147
- const syncActiveTabReadState = () => {
148
- if (!activeTabSessionKey || !activeTabUpdatedAt) {
149
- return;
150
- }
151
- presenter.chatSessionListManager.markSessionRead(
152
- activeTabSessionKey,
153
- activeTabUpdatedAt,
154
- );
155
- };
156
- syncActiveTabReadState();
157
- }, [activeTabSessionKey, activeTabUpdatedAt, presenter]);
158
-
159
- if (!activeTab) {
160
- return null;
161
- }
162
-
163
- return (
164
- <aside className="hidden md:flex md:w-[24rem] lg:w-[28rem] shrink-0 border-l border-gray-200/70 bg-white/90 backdrop-blur-sm">
165
- <div className="flex h-full min-h-0 w-full flex-col">
166
- <div className="border-b border-gray-200/70 px-4 py-3">
167
- <div className="flex items-center justify-between gap-3">
168
- <button
169
- type="button"
170
- onClick={onBackToParent}
171
- className={cn(
172
- "inline-flex items-center gap-1 text-xs font-medium text-gray-600 transition-colors hover:text-gray-900",
173
- !hasParentSession && "pointer-events-none opacity-0",
174
- )}
175
- >
176
- <ArrowLeft className="h-3.5 w-3.5" />
177
- <span>{t("chatBackToParent")}</span>
178
- </button>
179
- <button
180
- type="button"
181
- onClick={onClose}
182
- className="rounded-full border border-gray-200/80 p-1.5 text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-900"
183
- aria-label={t("chatChildSessionClosePanel")}
184
- >
185
- <X className="h-4 w-4" />
186
- </button>
187
- </div>
188
- {!shouldShowTabs ? (
189
- <div className="mt-3 flex min-w-0 items-center gap-2 text-sm font-semibold text-gray-900">
190
- {activeTab.agentId ? (
191
- <AgentIdentityAvatar
192
- agentId={activeTab.agentId}
193
- className="h-5 w-5 shrink-0"
194
- />
195
- ) : null}
196
- <span className="truncate" title={activeTab.sessionKey}>
197
- {activeTab.title}
198
- </span>
199
- </div>
200
- ) : null}
201
- {shouldShowTabs ? (
202
- <div className="mt-3 overflow-x-auto custom-scrollbar">
203
- <Tabs value={activeSessionKey} onValueChange={onSelectSession}>
204
- <TabsList className="h-auto min-w-max justify-start gap-1.5 rounded-none bg-transparent p-0 text-gray-500">
205
- {resolvedTabs.map((tab) => {
206
- const showUnreadDot = shouldShowUnreadSessionIndicator({
207
- active: tab.sessionKey === activeSessionKey,
208
- updatedAt: tab.updatedAt,
209
- readUpdatedAt: readUpdatedAtBySessionKey[tab.sessionKey],
210
- runStatus: tab.runStatus,
211
- });
212
- return (
213
- <TabsTrigger
214
- key={tab.sessionKey}
215
- value={tab.sessionKey}
216
- className="gap-2 rounded-full border border-gray-200/80 bg-white/85 px-2.5 py-1.5 text-xs font-medium text-gray-600 shadow-none hover:border-primary/30 hover:text-primary data-[state=active]:border-primary/30 data-[state=active]:bg-primary-50/70 data-[state=active]:text-primary data-[state=active]:shadow-sm"
217
- >
218
- {tab.agentId ? (
219
- <AgentIdentityAvatar
220
- agentId={tab.agentId}
221
- className="h-4 w-4 shrink-0"
222
- />
223
- ) : null}
224
- <span className="max-w-[132px] truncate">
225
- {tab.title}
226
- </span>
227
- {showUnreadDot ? (
228
- <span
229
- aria-label={t("chatSessionUnread")}
230
- className="h-2 w-2 shrink-0 rounded-full bg-primary"
231
- />
232
- ) : null}
233
- </TabsTrigger>
234
- );
235
- })}
236
- </TabsList>
237
- </Tabs>
238
- </div>
239
- ) : null}
240
- <ChildSessionPanelMetaStrip tab={activeTab} />
241
- </div>
242
-
243
- <div className="flex-1 min-h-0">
244
- {resolvedTabs.map((tab) => (
245
- <div
246
- key={tab.sessionKey}
247
- className={cn(
248
- "h-full",
249
- tab.sessionKey === activeSessionKey ? "block" : "hidden",
250
- )}
251
- >
252
- <ChildSessionPanelConversation
253
- sessionKey={tab.sessionKey}
254
- onToolAction={onToolAction}
255
- />
256
- </div>
257
- ))}
258
- </div>
259
- </div>
260
- </aside>
261
- );
262
- }