@nextclaw/ui 0.15.18 → 0.15.19

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 (107) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/assets/api-O5yEgzBt.js +13 -0
  3. package/dist/assets/app-presenter-provider-DXTYtH78.js +106 -0
  4. package/dist/assets/appearance-settings-page-BuGxSvlJ.js +1 -0
  5. package/dist/assets/{book-open-WsEnuW9P.js → book-open-HtUSPwoS.js} +1 -1
  6. package/dist/assets/card-GkBc-UMw.js +1 -0
  7. package/dist/assets/{channels-list-page-CAWuTHSM.js → channels-list-page-Bspr1Jp4.js} +2 -2
  8. package/dist/assets/chat-page-BKQ89f4s.js +1 -0
  9. package/dist/assets/config-split-page-CvLXSFSC.js +1 -0
  10. package/dist/assets/confirm-dialog-BVH7haN0.js +5 -0
  11. package/dist/assets/desktop-update-config-C9ZUI8UW.js +1 -0
  12. package/dist/assets/{dist-Ca-jiFrK.js → dist-CZx9Q6jc.js} +1 -1
  13. package/dist/assets/doc-browser-B4l0Xu7u.js +1 -0
  14. package/dist/assets/doc-browser-DsVF1DrS.js +1 -0
  15. package/dist/assets/doc-browser-context-Dy7EhLI8.js +1 -0
  16. package/dist/assets/{eye-B30J471A.js → eye-DU7p1-7X.js} +1 -1
  17. package/dist/assets/form-actions-aM9_jSJC.js +1 -0
  18. package/dist/assets/index-6pHX0DZH.js +2 -0
  19. package/dist/assets/index-DN6KM7WD.css +1 -0
  20. package/dist/assets/loader-circle-Dd6jw700.js +1 -0
  21. package/dist/assets/logo-badge-2-iV1pkr.js +1 -0
  22. package/dist/assets/mcp-marketplace-page-C-d0RMfg.js +1 -0
  23. package/dist/assets/mcp-marketplace-page-Dg03SZX1.js +9 -0
  24. package/dist/assets/model-config-page-DOBqLZoQ.js +1 -0
  25. package/dist/assets/{navigation-link-qPPUiLt0.js → navigation-link-Ct6xtnVM.js} +1 -1
  26. package/dist/assets/plus-CsgeRId8.js +1 -0
  27. package/dist/assets/{popover-DHx55dbc.js → popover-C2oIpGBF.js} +1 -1
  28. package/dist/assets/provider-scoped-model-input-DDqCdnTU.js +1 -0
  29. package/dist/assets/{providers-config-page-BwHtHIPe.js → providers-config-page-BAVPJKpx.js} +1 -1
  30. package/dist/assets/react-CeMr9V52.js +8 -0
  31. package/dist/assets/{refresh-cw-C7bynrWX.js → refresh-cw-BZ8giusN.js} +1 -1
  32. package/dist/assets/remote-C-r0SHcz.js +1 -0
  33. package/dist/assets/rotate-cw-DVdRfMSO.js +1 -0
  34. package/dist/assets/{runtime-config-page-BLrTVO3n.js → runtime-config-page-D0244uxJ.js} +1 -1
  35. package/dist/assets/{save-CsRsFtHS.js → save-CSzFGRse.js} +1 -1
  36. package/dist/assets/{search-D0HtJIL-.js → search-BmSWsiG2.js} +1 -1
  37. package/dist/assets/{search-config-page-n1GElgij.js → search-config-page-CrL1pUzy.js} +1 -1
  38. package/dist/assets/{secrets-config-page-DbUc3Ggi.js → secrets-config-page-BlgsD0-L.js} +2 -2
  39. package/dist/assets/security-config-cDrdpMJW.js +1 -0
  40. package/dist/assets/{select-C1zfp9zM.js → select-CklWb6Rs.js} +1 -1
  41. package/dist/assets/{settings-2-Ba3cLSN2.js → settings-2-BSZf8327.js} +1 -1
  42. package/dist/assets/skeleton-DG9u1BmA.js +1 -0
  43. package/dist/assets/{tabs-DmKgMKzb.js → tabs-Cah5klko.js} +1 -1
  44. package/dist/assets/{tag-chip-2vwlVUwM.js → tag-chip-DcrirDgN.js} +1 -1
  45. package/dist/assets/{trash-2-CUpWjNHu.js → trash-2-BLQOULWD.js} +1 -1
  46. package/dist/assets/use-config-CuFIsUVG.js +1 -0
  47. package/dist/assets/use-confirm-dialog-CcySmkWp.js +1 -0
  48. package/dist/assets/{use-viewport-layout-DaKJ-kap.js → use-viewport-layout-DU29bUJS.js} +1 -1
  49. package/dist/assets/x-BVoeXny1.js +1 -0
  50. package/dist/index.html +28 -28
  51. package/package.json +9 -9
  52. package/src/features/chat/features/message/components/__tests__/chat-inline-panel-app-card.test.tsx +35 -0
  53. package/src/features/chat/features/message/components/chat-inline-file-preview.tsx +3 -1
  54. package/src/features/chat/features/message/components/chat-inline-panel-app-card.tsx +13 -5
  55. package/src/features/chat/features/message/components/chat-message-list.container.tsx +1 -0
  56. package/src/features/chat/features/message/utils/__tests__/chat-message-show-content-tool-card.utils.test.ts +9 -0
  57. package/src/features/chat/features/message/utils/chat-inline-panel-app-card.utils.ts +4 -1
  58. package/src/features/chat/features/message/utils/chat-message-show-content-tool-card.utils.ts +29 -0
  59. package/src/features/chat/features/message/utils/chat-message-texts.utils.ts +1 -0
  60. package/src/features/chat/features/ncp/hooks/__tests__/use-ncp-agent-runtime-queue.test.tsx +32 -14
  61. package/src/features/chat/features/workspace/components/__tests__/workspace-file-content-preview.test.tsx +41 -0
  62. package/src/features/chat/features/workspace/components/chat-session-workspace-file-preview.tsx +4 -0
  63. package/src/features/chat/features/workspace/components/workspace-file-content-preview.tsx +15 -2
  64. package/src/features/chat/features/workspace/utils/chat-workspace-file-tab-persistence.utils.ts +11 -0
  65. package/src/features/chat/features/workspace/utils/chat-workspace-file-tab.utils.ts +1 -0
  66. package/src/features/chat/managers/__tests__/chat-thread.manager.test.ts +11 -8
  67. package/src/features/chat/managers/__tests__/chat-ui.manager.test.ts +6 -0
  68. package/src/features/chat/managers/chat-thread.manager.ts +2 -0
  69. package/src/features/chat/managers/chat-ui.manager.ts +10 -4
  70. package/src/features/chat/stores/__tests__/chat-thread.store.test.ts +4 -0
  71. package/src/features/chat/stores/chat-thread.store.ts +6 -1
  72. package/src/shared/components/doc-browser/__tests__/doc-browser-context.test.tsx +32 -0
  73. package/src/shared/components/doc-browser/doc-browser-panel-parts.tsx +2 -0
  74. package/src/shared/components/doc-browser/managers/doc-browser.manager.ts +20 -38
  75. package/src/shared/components/doc-browser/types/doc-browser.types.ts +5 -0
  76. package/src/shared/components/doc-browser/utils/doc-browser-state.utils.ts +63 -0
  77. package/src/shared/lib/i18n/locales/en-US/chat.json +1 -0
  78. package/src/shared/lib/i18n/locales/zh-CN/chat.json +1 -0
  79. package/dist/assets/api-D5UCLVE_.js +0 -13
  80. package/dist/assets/app-presenter-provider-De7Zwitu.js +0 -106
  81. package/dist/assets/appearance-settings-page-BkQaPtQ-.js +0 -1
  82. package/dist/assets/card-xVrS1b1T.js +0 -1
  83. package/dist/assets/chat-page-AvOuaxuv.js +0 -1
  84. package/dist/assets/config-split-page-xj0UtMow.js +0 -1
  85. package/dist/assets/confirm-dialog-e2YCUzt1.js +0 -5
  86. package/dist/assets/desktop-update-config-D5NIaimo.js +0 -1
  87. package/dist/assets/doc-browser-B2tNEKrJ.js +0 -1
  88. package/dist/assets/doc-browser-CZX6I6CU.js +0 -1
  89. package/dist/assets/doc-browser-context-CGz0LULR.js +0 -1
  90. package/dist/assets/form-actions-CnSzu3WD.js +0 -1
  91. package/dist/assets/index-B5AoUrMf.js +0 -2
  92. package/dist/assets/index-QveCjxCj.css +0 -1
  93. package/dist/assets/loader-circle-DjwSRQHW.js +0 -1
  94. package/dist/assets/logo-badge-CISsltAo.js +0 -1
  95. package/dist/assets/mcp-marketplace-page-BZa7p7Qf.js +0 -1
  96. package/dist/assets/mcp-marketplace-page-CPcPzMUQ.js +0 -9
  97. package/dist/assets/model-config-page-D6ex3_NM.js +0 -1
  98. package/dist/assets/plus-C45awBb1.js +0 -1
  99. package/dist/assets/provider-scoped-model-input-1TJxAhx6.js +0 -1
  100. package/dist/assets/react-DerwD2EA.js +0 -8
  101. package/dist/assets/remote-B6TXClIg.js +0 -1
  102. package/dist/assets/rotate-cw-Bhx0XkQP.js +0 -1
  103. package/dist/assets/security-config-n2WHhHXV.js +0 -1
  104. package/dist/assets/skeleton-DL5npsVL.js +0 -1
  105. package/dist/assets/use-config-BvxDWV-M.js +0 -1
  106. package/dist/assets/use-confirm-dialog-CeUEE4p5.js +0 -1
  107. package/dist/assets/x-DGdYT7rH.js +0 -1
@@ -269,6 +269,9 @@ describe('DocBrowserProvider panel app resources', () => {
269
269
 
270
270
  act(() => {
271
271
  result.current.openTarget({
272
+ contentParams: {
273
+ file: { path: '/tmp/photo.png' },
274
+ },
272
275
  dedupeKey: 'panel-app:demo',
273
276
  dockIcon: { type: 'url', url: '/api/panel-apps/demo/assets/icon.png' },
274
277
  historyPolicy: 'managed',
@@ -281,6 +284,9 @@ describe('DocBrowserProvider panel app resources', () => {
281
284
 
282
285
  expect(result.current.currentTab).toMatchObject({
283
286
  currentUrl: '/api/panel-apps/demo/content',
287
+ contentParams: {
288
+ file: { path: '/tmp/photo.png' },
289
+ },
284
290
  dedupeKey: 'panel-app:demo',
285
291
  dockIcon: { type: 'url', url: '/api/panel-apps/demo/assets/icon.png' },
286
292
  kind: 'panel-app',
@@ -288,6 +294,32 @@ describe('DocBrowserProvider panel app resources', () => {
288
294
  title: 'Demo Panel App',
289
295
  });
290
296
  });
297
+
298
+ it('reloads a reused Panel App tab when its params change', () => {
299
+ const { result } = renderHook(() => useDocBrowser(), { wrapper });
300
+ const openPanelApp = (path: string) => {
301
+ result.current.openTarget({
302
+ contentParams: { file: { path } },
303
+ dedupeKey: 'panel-app:demo',
304
+ historyPolicy: 'managed',
305
+ kind: 'panel-app',
306
+ resourceUri: 'nextclaw://panel-app/demo',
307
+ title: 'Demo Panel App',
308
+ url: '/api/panel-apps/demo/content',
309
+ });
310
+ };
311
+
312
+ act(() => openPanelApp('/tmp/first.png'));
313
+ const firstNavVersion = result.current.currentTab?.navVersion;
314
+ act(() => openPanelApp('/tmp/second.png'));
315
+
316
+ expect(result.current.currentTab).toMatchObject({
317
+ contentParams: {
318
+ file: { path: '/tmp/second.png' },
319
+ },
320
+ navVersion: (firstNavVersion ?? 0) + 1,
321
+ });
322
+ });
291
323
  });
292
324
 
293
325
  describe('DocBrowserProvider managed history', () => {
@@ -10,6 +10,7 @@ import {
10
10
  import { IconActionButton } from '@/shared/components/ui/actions/icon-action-button';
11
11
  import { NavigationLink } from '@/shared/components/actions/navigation-link';
12
12
  import { t } from '@/shared/lib/i18n';
13
+ import { createUiContentParamsWindowName } from '@nextclaw/shared';
13
14
 
14
15
  type DocBrowserAddressToolbarProps = {
15
16
  isVisible: boolean;
@@ -86,6 +87,7 @@ export function DocBrowserFrameContent({
86
87
  ref={iframeRef}
87
88
  key={iframeInstanceId}
88
89
  src={currentUrl}
90
+ name={createUiContentParamsWindowName(currentTab?.contentParams)}
89
91
  className="absolute inset-0 w-full h-full border-0"
90
92
  title={currentTab?.title || 'NextClaw Docs'}
91
93
  sandbox={iframeSandbox}
@@ -8,10 +8,12 @@ import type {
8
8
  DocBrowserTab,
9
9
  } from '@/shared/components/doc-browser/types/doc-browser.types';
10
10
  import {
11
+ appendManualNavigation,
11
12
  createDocBrowserActiveHistoryEntry,
12
13
  createDefaultDocBrowserState,
13
14
  createDocBrowserTab,
14
15
  normalizeDocBrowserDockedWidth,
16
+ updateTabForOpen,
15
17
  } from '@/shared/components/doc-browser/utils/doc-browser-state.utils';
16
18
  import {
17
19
  DOC_BROWSER_HOME_TAB_KIND,
@@ -45,14 +47,6 @@ function updateActiveTab(state: DocBrowserState, updater: (tab: DocBrowserTab) =
45
47
  return updateTab(state, state.activeTabId, updater);
46
48
  }
47
49
 
48
- function appendManualNavigation(tab: DocBrowserTab, url: string): Pick<DocBrowserTab, 'history' | 'historyIndex'> {
49
- const history = [...tab.history.slice(0, tab.historyIndex + 1), url];
50
- return {
51
- history,
52
- historyIndex: history.length - 1,
53
- };
54
- }
55
-
56
50
  function areActiveHistoryEntriesEquivalent(
57
51
  routeResolver: DocBrowserRouteResolver,
58
52
  current: DocBrowserActiveHistoryEntry,
@@ -140,34 +134,6 @@ function restoreActiveHistoryEntry(
140
134
  );
141
135
  }
142
136
 
143
- function updateTabForOpen(
144
- routeResolver: DocBrowserRouteResolver,
145
- tab: DocBrowserTab,
146
- target: DocBrowserRouteTarget,
147
- options?: DocBrowserOpenOptions,
148
- dedupeKey?: string,
149
- ): DocBrowserTab {
150
- const baseTab = {
151
- ...tab,
152
- title: options?.title || target.title || tab.title,
153
- kind: target.kind,
154
- resourceUri: target.resourceUri ?? target.url,
155
- dockIcon: options?.dockIcon ?? target.dockIcon,
156
- dedupeKey,
157
- };
158
-
159
- if (routeResolver.areUrlsEquivalent(tab.currentUrl, target.url, tab.kind, target.kind)) {
160
- return baseTab;
161
- }
162
-
163
- return {
164
- ...baseTab,
165
- currentUrl: target.url,
166
- ...appendManualNavigation(tab, target.url),
167
- navVersion: tab.navVersion + 1,
168
- };
169
- }
170
-
171
137
  function isClosedDefaultHomeState(state: DocBrowserState, activeTab?: DocBrowserTab): boolean {
172
138
  return !state.isOpen
173
139
  && state.tabs.length === 1
@@ -213,7 +179,15 @@ function openResolvedDocBrowserState(
213
179
  }
214
180
 
215
181
  if (shouldForceNewTab || dedupeKey || !activeTab || activeTab.kind !== target.kind) {
216
- const newTab = createDocBrowserTab(target.url, target.kind, title ?? target.title, dedupeKey, target.resourceUri ?? target.url, options?.dockIcon ?? target.dockIcon);
182
+ const newTab = createDocBrowserTab(
183
+ target.url,
184
+ target.kind,
185
+ title ?? target.title,
186
+ dedupeKey,
187
+ target.resourceUri ?? target.url,
188
+ options?.dockIcon ?? target.dockIcon,
189
+ target.contentParams,
190
+ );
217
191
  if (isClosedDefaultHomeState(prev, activeTab)) {
218
192
  const nextState = {
219
193
  ...prev,
@@ -257,7 +231,15 @@ function openDocBrowserState(
257
231
  kind: options?.kind,
258
232
  url,
259
233
  });
260
- return openResolvedDocBrowserState(routeResolver, prev, target, options);
234
+ return openResolvedDocBrowserState(
235
+ routeResolver,
236
+ prev,
237
+ {
238
+ ...target,
239
+ contentParams: options?.contentParams,
240
+ },
241
+ options,
242
+ );
261
243
  }
262
244
 
263
245
  export class DocBrowserManager {
@@ -1,3 +1,5 @@
1
+ import type { UiContentParams } from '@nextclaw/shared';
2
+
1
3
  export type DocBrowserMode = 'floating' | 'docked';
2
4
  export type DocBrowserTabKind = 'docs' | 'content' | (string & {});
3
5
 
@@ -7,6 +9,7 @@ export type DocBrowserTab = {
7
9
  title: string;
8
10
  currentUrl: string;
9
11
  resourceUri?: string;
12
+ contentParams?: UiContentParams;
10
13
  dockIcon?: DocBrowserDockIcon;
11
14
  dedupeKey?: string;
12
15
  history: string[];
@@ -21,6 +24,7 @@ export type DocBrowserRouteTarget = {
21
24
  historyPolicy: 'managed' | 'none';
22
25
  kind: DocBrowserTabKind;
23
26
  resourceUri?: string;
27
+ contentParams?: UiContentParams;
24
28
  title: string;
25
29
  url: string;
26
30
  };
@@ -71,6 +75,7 @@ export type DocBrowserOpenOptions = {
71
75
  newTab?: boolean;
72
76
  title?: string;
73
77
  kind?: DocBrowserTabKind;
78
+ contentParams?: UiContentParams;
74
79
  };
75
80
 
76
81
  export type DocBrowserState = {
@@ -1,6 +1,9 @@
1
1
  import type {
2
2
  DocBrowserActiveHistoryEntry,
3
3
  DocBrowserDockIcon,
4
+ DocBrowserOpenOptions,
5
+ DocBrowserRouteResolver,
6
+ DocBrowserRouteTarget,
4
7
  DocBrowserState,
5
8
  DocBrowserTab,
6
9
  DocBrowserTabKind,
@@ -11,6 +14,10 @@ import {
11
14
  inferTabTitle,
12
15
  } from './doc-browser-url.utils';
13
16
  import { t } from '@/shared/lib/i18n';
17
+ import {
18
+ createUiContentParamsWindowName,
19
+ type UiContentParams,
20
+ } from '@nextclaw/shared';
14
21
 
15
22
  export const DOC_BROWSER_DOCKED_DEFAULT_WIDTH = 420;
16
23
  export const DOC_BROWSER_DOCKED_MIN_WIDTH = 320;
@@ -36,6 +43,7 @@ export function createDocBrowserTab(
36
43
  dedupeKey?: string,
37
44
  resourceUri?: string,
38
45
  dockIcon?: DocBrowserDockIcon,
46
+ contentParams?: UiContentParams,
39
47
  ): DocBrowserTab {
40
48
  const tabTitle = title?.trim() || inferTabTitle(url, kind, kind === 'docs' ? t('docBrowserHelp') : 'Detail');
41
49
  const normalizedResourceUri = resourceUri?.trim();
@@ -46,6 +54,7 @@ export function createDocBrowserTab(
46
54
  title: tabTitle,
47
55
  currentUrl: url,
48
56
  resourceUri: normalizedResourceUri ? normalizedResourceUri : undefined,
57
+ contentParams,
49
58
  dockIcon,
50
59
  dedupeKey,
51
60
  history: [url],
@@ -54,6 +63,60 @@ export function createDocBrowserTab(
54
63
  };
55
64
  }
56
65
 
66
+ export function appendManualNavigation(
67
+ tab: DocBrowserTab,
68
+ url: string,
69
+ ): Pick<DocBrowserTab, 'history' | 'historyIndex'> {
70
+ const history = [...tab.history.slice(0, tab.historyIndex + 1), url];
71
+ return {
72
+ history,
73
+ historyIndex: history.length - 1,
74
+ };
75
+ }
76
+
77
+ export function updateTabForOpen(
78
+ routeResolver: DocBrowserRouteResolver,
79
+ tab: DocBrowserTab,
80
+ target: DocBrowserRouteTarget,
81
+ options?: DocBrowserOpenOptions,
82
+ dedupeKey?: string,
83
+ ): DocBrowserTab {
84
+ const baseTab = {
85
+ ...tab,
86
+ title: options?.title || target.title || tab.title,
87
+ kind: target.kind,
88
+ resourceUri: target.resourceUri ?? target.url,
89
+ dockIcon: options?.dockIcon ?? target.dockIcon,
90
+ dedupeKey,
91
+ contentParams: target.contentParams,
92
+ };
93
+ const hasSameUrl = routeResolver.areUrlsEquivalent(
94
+ tab.currentUrl,
95
+ target.url,
96
+ tab.kind,
97
+ target.kind,
98
+ );
99
+ if (
100
+ hasSameUrl &&
101
+ createUiContentParamsWindowName(tab.contentParams) ===
102
+ createUiContentParamsWindowName(target.contentParams)
103
+ ) {
104
+ return baseTab;
105
+ }
106
+ if (hasSameUrl) {
107
+ return {
108
+ ...baseTab,
109
+ navVersion: tab.navVersion + 1,
110
+ };
111
+ }
112
+ return {
113
+ ...baseTab,
114
+ currentUrl: target.url,
115
+ ...appendManualNavigation(tab, target.url),
116
+ navVersion: tab.navVersion + 1,
117
+ };
118
+ }
119
+
57
120
  export function createDocBrowserActiveHistoryEntry(tab: DocBrowserTab): DocBrowserActiveHistoryEntry {
58
121
  return {
59
122
  kind: tab.kind,
@@ -388,6 +388,7 @@
388
388
  "chatMessageCopy": "Copy",
389
389
  "chatMessageCopied": "Copied",
390
390
  "chatMermaidDiagram": "Diagram",
391
+ "chatMermaidExpand": "Expand diagram",
391
392
  "chatMermaidLoading": "Rendering diagram…",
392
393
  "chatMermaidRenderError": "Diagram could not be rendered; showing source instead",
393
394
  "chatSidebarNewTask": "New Task",
@@ -388,6 +388,7 @@
388
388
  "chatMessageCopy": "复制",
389
389
  "chatMessageCopied": "已复制",
390
390
  "chatMermaidDiagram": "图表",
391
+ "chatMermaidExpand": "放大图表",
391
392
  "chatMermaidLoading": "正在渲染图表…",
392
393
  "chatMermaidRenderError": "图表无法渲染,已显示源代码",
393
394
  "chatSidebarNewTask": "新任务",