@nextclaw/ui 0.12.35-beta.6 → 0.12.35

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 (85) hide show
  1. package/CHANGELOG.md +482 -0
  2. package/dist/assets/api-DruAcori.js +15 -0
  3. package/dist/assets/{book-open-qc0UVn6m.js → book-open-cPX0Za7Z.js} +1 -1
  4. package/dist/assets/channels-list-page-DXH1qYLs.js +8 -0
  5. package/dist/assets/chat-page-Cpo0AFHb.js +105 -0
  6. package/dist/assets/{config-split-page-DW8tP9Bc.js → config-split-page-BFh_Qixx.js} +1 -1
  7. package/dist/assets/confirm-dialog-B0TP-vPd.js +5 -0
  8. package/dist/assets/{createLucideIcon-CA0sgoMJ.js → createLucideIcon-Br1EFMEr.js} +1 -1
  9. package/dist/assets/{desktop-update-config-DARSwQG8.js → desktop-update-config-Be8x1jNy.js} +1 -1
  10. package/dist/assets/{dist-D5zsy7pX.js → dist-CpwDZDtv.js} +1 -1
  11. package/dist/assets/{dist-DNxIa3pe.js → dist-rzakR_bu.js} +1 -1
  12. package/dist/assets/doc-browser-BI7HSaMK.js +3 -0
  13. package/dist/assets/doc-browser-context-DB6TTHeE.js +1 -0
  14. package/dist/assets/doc-browser-route-registry.utils-x5ijvk0u.js +1 -0
  15. package/dist/assets/doc-browser-yTfN7UBH.js +1 -0
  16. package/dist/assets/{external-link-C9fbyi6k.js → external-link-C3usm3se.js} +1 -1
  17. package/dist/assets/index-GVTiCf1s.js +101 -0
  18. package/dist/assets/index-v0fAGXQW.css +1 -0
  19. package/dist/assets/{mcp-marketplace-page-BiExW5wq.js → mcp-marketplace-page-DDjeHd1I.js} +2 -2
  20. package/dist/assets/mcp-marketplace-page-WUkc7n94.js +1 -0
  21. package/dist/assets/model-config-BjXMpU9U.js +1 -0
  22. package/dist/assets/play-CqNi0u02.js +1 -0
  23. package/dist/assets/plus-BcIC8dG1.js +1 -0
  24. package/dist/assets/{provider-scoped-model-input-Bk8jlpRm.js → provider-scoped-model-input-t1tCP5y5.js} +1 -1
  25. package/dist/assets/providers-list-C1D5p9kK.js +1 -0
  26. package/dist/assets/react-B2X_ph0a.js +1 -0
  27. package/dist/assets/remote-BHeENKxL.js +1 -0
  28. package/dist/assets/runtime-config-page--O0Wq01S.js +1 -0
  29. package/dist/assets/{save-CG4Hb1u8.js → save-D10M5vQg.js} +1 -1
  30. package/dist/assets/{search-lWpOIHEn.js → search-CdhgFNwf.js} +1 -1
  31. package/dist/assets/search-config-Dzpizo-_.js +1 -0
  32. package/dist/assets/{secrets-config-ZbLzjIRx.js → secrets-config-D1AUSEXX.js} +1 -1
  33. package/dist/assets/{setting-row-CNfTKDjc.js → setting-row-8VkukJoH.js} +1 -1
  34. package/dist/assets/{tabs-custom-BbZoysAl.js → tabs-custom-BBXu1OGs.js} +1 -1
  35. package/dist/assets/{tag-chip-Dl8JbhC7.js → tag-chip-ix15P-r4.js} +1 -1
  36. package/dist/assets/wrench-qVIwShTF.js +1 -0
  37. package/dist/assets/x-Chb07O-Y.js +1 -0
  38. package/dist/index.html +17 -15
  39. package/package.json +8 -8
  40. package/src/features/panel-apps/components/panel-app-list-item.test.tsx +60 -0
  41. package/src/features/panel-apps/components/panel-app-list-item.tsx +120 -30
  42. package/src/features/panel-apps/components/panel-apps-list.tsx +8 -1
  43. package/src/features/panel-apps/hooks/use-panel-apps.ts +10 -0
  44. package/src/features/panel-apps/managers/panel-app-bridge.manager.test.ts +153 -1
  45. package/src/features/panel-apps/managers/panel-app-bridge.manager.ts +126 -9
  46. package/src/features/panel-apps/utils/panel-app-doc-browser.utils.tsx +7 -3
  47. package/src/features/panel-apps/utils/panel-app-view.utils.test.ts +66 -0
  48. package/src/features/panel-apps/utils/panel-app-view.utils.ts +13 -2
  49. package/src/index.css +23 -0
  50. package/src/shared/components/doc-browser/doc-browser-context.test.tsx +170 -0
  51. package/src/shared/components/doc-browser/doc-browser-context.tsx +3 -0
  52. package/src/shared/components/doc-browser/doc-browser-home-page.tsx +95 -0
  53. package/src/shared/components/doc-browser/doc-browser-panel-parts.tsx +3 -97
  54. package/src/shared/components/doc-browser/doc-browser-renderer.types.ts +1 -0
  55. package/src/shared/components/doc-browser/doc-browser-tab-strip.tsx +117 -44
  56. package/src/shared/components/doc-browser/doc-browser.test.tsx +159 -1
  57. package/src/shared/components/doc-browser/doc-browser.tsx +46 -27
  58. package/src/shared/components/doc-browser/managers/doc-browser.manager.ts +183 -71
  59. package/src/shared/components/doc-browser/stores/doc-browser.store.ts +52 -1
  60. package/src/shared/components/doc-browser/types/doc-browser.types.ts +9 -0
  61. package/src/shared/components/doc-browser/utils/doc-browser-route-registry.utils.ts +232 -0
  62. package/src/shared/components/doc-browser/utils/doc-browser-state.utils.ts +11 -0
  63. package/src/shared/components/doc-browser/utils/doc-browser-url.utils.ts +2 -0
  64. package/src/shared/lib/api/types.ts +1 -0
  65. package/src/shared/lib/i18n/runtime/doc-browser-labels.utils.ts +10 -0
  66. package/dist/assets/api-BTZui7nj.js +0 -15
  67. package/dist/assets/channels-list-page-DBtU_M1Y.js +0 -8
  68. package/dist/assets/chat-page-BcoJYo91.js +0 -105
  69. package/dist/assets/doc-browser-B9skxzVo.js +0 -1
  70. package/dist/assets/doc-browser-CwyITRXx.js +0 -1
  71. package/dist/assets/doc-browser-context-Do2qSrB8.js +0 -1
  72. package/dist/assets/index-BYRP_BMj.css +0 -1
  73. package/dist/assets/index-DckPGTdM.js +0 -103
  74. package/dist/assets/mcp-marketplace-page-Cj6MDSkE.js +0 -1
  75. package/dist/assets/model-config-DbdY7fF1.js +0 -1
  76. package/dist/assets/notice-card-CyiVcu_Z.js +0 -5
  77. package/dist/assets/play-D-s0C4MN.js +0 -1
  78. package/dist/assets/plus-DOwjM_kF.js +0 -1
  79. package/dist/assets/providers-list-CJjNStDV.js +0 -1
  80. package/dist/assets/react-BaRotFd6.js +0 -1
  81. package/dist/assets/remote-gl8QckNc.js +0 -1
  82. package/dist/assets/runtime-config-page-BMFc1yzf.js +0 -1
  83. package/dist/assets/search-config-DUOR26if.js +0 -1
  84. package/dist/assets/x-D6GwT_8k.js +0 -1
  85. /package/dist/assets/{config-hints-CTqBnCDp.js → config-hints-CY1lg9IE.js} +0 -0
@@ -13,6 +13,12 @@ export type DocBrowserTab = {
13
13
  navVersion: number;
14
14
  };
15
15
 
16
+ export type DocBrowserActiveHistoryEntry = {
17
+ kind: DocBrowserTabKind;
18
+ tabId: string;
19
+ url: string;
20
+ };
21
+
16
22
  export type DocBrowserOpenOptions = {
17
23
  activate?: boolean;
18
24
  dedupeKey?: string;
@@ -26,12 +32,15 @@ export type DocBrowserState = {
26
32
  mode: DocBrowserMode;
27
33
  tabs: DocBrowserTab[];
28
34
  activeTabId: string;
35
+ activeHistory: DocBrowserActiveHistoryEntry[];
36
+ activeHistoryIndex: number;
29
37
  };
30
38
 
31
39
  export type DocBrowserStateUpdate = DocBrowserState | ((prev: DocBrowserState) => DocBrowserState);
32
40
 
33
41
  export type DocBrowserActions = {
34
42
  open: (url?: string, options?: DocBrowserOpenOptions) => void;
43
+ openNewTab: () => void;
35
44
  close: () => void;
36
45
  toggleMode: () => void;
37
46
  navigate: (url: string) => void;
@@ -0,0 +1,232 @@
1
+ import type {
2
+ DocBrowserOpenOptions,
3
+ DocBrowserTab,
4
+ DocBrowserTabKind,
5
+ } from '@/shared/components/doc-browser/types/doc-browser.types';
6
+ import { t } from '@/shared/lib/i18n';
7
+ import {
8
+ DOCS_DEFAULT_BASE_URL,
9
+ DOC_BROWSER_HOME_TAB_KIND,
10
+ DOC_BROWSER_HOME_URL,
11
+ getDefaultDocsUrl,
12
+ inferTabTitle,
13
+ isDocsUrl,
14
+ normalizeDocUrl,
15
+ normalizeUrlByKind,
16
+ } from './doc-browser-url.utils';
17
+
18
+ export const DOC_BROWSER_APPS_TAB_KIND = 'apps';
19
+ export const DOC_BROWSER_APPS_URL = 'nextclaw://apps';
20
+ export const DOC_BROWSER_SERVICE_APPS_URL = `${DOC_BROWSER_APPS_URL}?tab=service-apps`;
21
+
22
+ type DocBrowserHistoryPolicy = 'managed' | 'none';
23
+
24
+ type DocBrowserRouteDefinition = {
25
+ defaultUrl: () => string;
26
+ getDedupeKey?: (url: string) => string | undefined;
27
+ getTitle: (url: string) => string;
28
+ historyPolicy: DocBrowserHistoryPolicy;
29
+ id: string;
30
+ kind: DocBrowserTabKind;
31
+ matchUrl: (url: string) => boolean;
32
+ normalizeUrl: (url: string) => string;
33
+ urlsEquivalent?: (currentUrl: string, nextUrl: string) => boolean;
34
+ };
35
+
36
+ type DocBrowserResolvedRoute = {
37
+ dedupeKey?: string;
38
+ historyPolicy: DocBrowserHistoryPolicy;
39
+ kind: DocBrowserTabKind;
40
+ title: string;
41
+ url: string;
42
+ };
43
+
44
+ export type DocBrowserNavigationTarget =
45
+ | {
46
+ type: 'doc-browser';
47
+ options?: DocBrowserOpenOptions;
48
+ url?: string;
49
+ }
50
+ | {
51
+ path: string;
52
+ type: 'app-route';
53
+ };
54
+
55
+ export type DocBrowserHomeNavigationItem = {
56
+ id: string;
57
+ label: string;
58
+ target: DocBrowserNavigationTarget;
59
+ };
60
+
61
+ function isUrlWithPrefix(url: string, prefix: string): boolean {
62
+ return url === prefix || url.startsWith(`${prefix}?`) || url.startsWith(`${prefix}/`);
63
+ }
64
+
65
+ function normalizeAppsUrl(url: string): string {
66
+ try {
67
+ const parsed = new URL(url);
68
+ const tab = parsed.searchParams.get('tab');
69
+ return tab === 'service-apps' ? DOC_BROWSER_SERVICE_APPS_URL : DOC_BROWSER_APPS_URL;
70
+ } catch {
71
+ return DOC_BROWSER_APPS_URL;
72
+ }
73
+ }
74
+
75
+ function inferFallbackKind(url?: string): DocBrowserTabKind {
76
+ return url && isDocsUrl(url) ? 'docs' : 'content';
77
+ }
78
+
79
+ class FallbackDocBrowserRouteDefinition implements DocBrowserRouteDefinition {
80
+ readonly historyPolicy = 'managed';
81
+
82
+ readonly id: string;
83
+
84
+ constructor(readonly kind: DocBrowserTabKind) {
85
+ this.id = `fallback:${kind}`;
86
+ }
87
+
88
+ defaultUrl = (): string => this.kind === 'docs' ? DOCS_DEFAULT_BASE_URL : 'about:blank';
89
+
90
+ getTitle = (url: string): string => inferTabTitle(url, this.kind, this.kind === 'docs' ? 'Docs' : 'Detail');
91
+
92
+ matchUrl = (): boolean => false;
93
+
94
+ normalizeUrl = (url: string): string => normalizeUrlByKind(url, this.kind);
95
+
96
+ urlsEquivalent = (currentUrl: string, nextUrl: string): boolean => currentUrl === nextUrl;
97
+ }
98
+
99
+ const DOC_BROWSER_ROUTE_DEFINITIONS: DocBrowserRouteDefinition[] = [
100
+ {
101
+ defaultUrl: () => DOC_BROWSER_HOME_URL,
102
+ getTitle: () => t('docBrowserHomeTitle'),
103
+ historyPolicy: 'managed',
104
+ id: 'home',
105
+ kind: DOC_BROWSER_HOME_TAB_KIND,
106
+ matchUrl: (url) => url === DOC_BROWSER_HOME_URL,
107
+ normalizeUrl: () => DOC_BROWSER_HOME_URL,
108
+ urlsEquivalent: (currentUrl, nextUrl) => currentUrl === nextUrl,
109
+ },
110
+ {
111
+ defaultUrl: getDefaultDocsUrl,
112
+ getTitle: () => 'Docs',
113
+ historyPolicy: 'managed',
114
+ id: 'docs',
115
+ kind: 'docs',
116
+ matchUrl: isDocsUrl,
117
+ normalizeUrl: (url) => normalizeUrlByKind(url, 'docs'),
118
+ urlsEquivalent: (currentUrl, nextUrl) => normalizeDocUrl(currentUrl) === normalizeDocUrl(nextUrl),
119
+ },
120
+ {
121
+ defaultUrl: () => DOC_BROWSER_APPS_URL,
122
+ getDedupeKey: () => 'apps',
123
+ getTitle: (url) => normalizeAppsUrl(url) === DOC_BROWSER_SERVICE_APPS_URL
124
+ ? t('serviceAppsTitle')
125
+ : t('appsTitle'),
126
+ historyPolicy: 'managed',
127
+ id: 'apps',
128
+ kind: DOC_BROWSER_APPS_TAB_KIND,
129
+ matchUrl: (url) => isUrlWithPrefix(url, DOC_BROWSER_APPS_URL),
130
+ normalizeUrl: normalizeAppsUrl,
131
+ urlsEquivalent: (currentUrl, nextUrl) => normalizeAppsUrl(currentUrl) === normalizeAppsUrl(nextUrl),
132
+ },
133
+ ];
134
+
135
+ export class DocBrowserRouteRegistry {
136
+ private readonly routeDefinitions = DOC_BROWSER_ROUTE_DEFINITIONS;
137
+
138
+ resolveOpenTarget = (params: {
139
+ activeTab?: DocBrowserTab;
140
+ kind?: DocBrowserTabKind;
141
+ url?: string;
142
+ }): DocBrowserResolvedRoute => {
143
+ const { activeTab, kind, url: requestedUrl } = params;
144
+ const route = this.resolveRouteDefinition(requestedUrl, kind, activeTab);
145
+ const rawUrl = requestedUrl?.trim()
146
+ || (!kind && activeTab && activeTab.kind !== 'docs'
147
+ ? activeTab.currentUrl
148
+ : route.defaultUrl());
149
+ const url = route.normalizeUrl(rawUrl);
150
+ return {
151
+ dedupeKey: route.getDedupeKey?.(url),
152
+ historyPolicy: route.historyPolicy,
153
+ kind: route.kind,
154
+ title: route.getTitle(url),
155
+ url,
156
+ };
157
+ };
158
+
159
+ areUrlsEquivalent = (
160
+ currentUrl: string,
161
+ nextUrl: string,
162
+ currentKind: DocBrowserTabKind,
163
+ nextKind: DocBrowserTabKind,
164
+ ): boolean => {
165
+ if (currentKind !== nextKind) {
166
+ return false;
167
+ }
168
+ const route = this.resolveRouteDefinition(currentUrl, currentKind);
169
+ return route.urlsEquivalent?.(currentUrl, nextUrl) ?? currentUrl === nextUrl;
170
+ };
171
+
172
+ usesManagedHistory = (tab: DocBrowserTab): boolean => {
173
+ return this.resolveRouteDefinition(tab.currentUrl, tab.kind).historyPolicy === 'managed';
174
+ };
175
+
176
+ getHomeNavigationItems = (): DocBrowserHomeNavigationItem[] => [
177
+ {
178
+ id: 'apps',
179
+ label: t('appsTitle'),
180
+ target: { type: 'doc-browser', url: DOC_BROWSER_APPS_URL },
181
+ },
182
+ {
183
+ id: 'service-apps',
184
+ label: t('serviceAppsTitle'),
185
+ target: { type: 'doc-browser', url: DOC_BROWSER_SERVICE_APPS_URL },
186
+ },
187
+ {
188
+ id: 'docs',
189
+ label: t('docBrowserHelp'),
190
+ target: {
191
+ options: { newTab: true },
192
+ type: 'doc-browser',
193
+ url: getDefaultDocsUrl(),
194
+ },
195
+ },
196
+ {
197
+ id: 'skill-marketplace',
198
+ label: t('marketplaceSkillsPageTitle'),
199
+ target: { path: '/marketplace/skills', type: 'app-route' },
200
+ },
201
+ {
202
+ id: 'mcp-marketplace',
203
+ label: t('marketplaceMcpPageTitle'),
204
+ target: { path: '/marketplace/mcp', type: 'app-route' },
205
+ },
206
+ ];
207
+
208
+ private resolveRouteDefinition = (
209
+ url?: string,
210
+ kind?: DocBrowserTabKind,
211
+ activeTab?: DocBrowserTab,
212
+ ): DocBrowserRouteDefinition => {
213
+ const targetKind = kind ?? (url ? undefined : activeTab?.kind);
214
+ const routeByKind = targetKind
215
+ ? this.routeDefinitions.find((route) => route.kind === targetKind)
216
+ : undefined;
217
+ if (routeByKind) {
218
+ return routeByKind;
219
+ }
220
+
221
+ const routeByUrl = url
222
+ ? this.routeDefinitions.find((route) => route.matchUrl(url))
223
+ : undefined;
224
+ if (routeByUrl) {
225
+ return routeByUrl;
226
+ }
227
+
228
+ return new FallbackDocBrowserRouteDefinition(kind ?? activeTab?.kind ?? inferFallbackKind(url));
229
+ };
230
+ }
231
+
232
+ export const docBrowserRouteRegistry = new DocBrowserRouteRegistry();
@@ -1,4 +1,5 @@
1
1
  import type {
2
+ DocBrowserActiveHistoryEntry,
2
3
  DocBrowserState,
3
4
  DocBrowserTab,
4
5
  DocBrowserTabKind,
@@ -35,6 +36,14 @@ export function createDocBrowserTab(
35
36
  };
36
37
  }
37
38
 
39
+ export function createDocBrowserActiveHistoryEntry(tab: DocBrowserTab): DocBrowserActiveHistoryEntry {
40
+ return {
41
+ kind: tab.kind,
42
+ tabId: tab.id,
43
+ url: tab.currentUrl,
44
+ };
45
+ }
46
+
38
47
  export function createDefaultDocBrowserState(): DocBrowserState {
39
48
  const initialUrl = getDefaultDocsUrl();
40
49
  const initialTab = createDocBrowserTab(initialUrl, 'docs', 'Docs');
@@ -43,5 +52,7 @@ export function createDefaultDocBrowserState(): DocBrowserState {
43
52
  mode: 'docked',
44
53
  tabs: [initialTab],
45
54
  activeTabId: initialTab.id,
55
+ activeHistory: [createDocBrowserActiveHistoryEntry(initialTab)],
56
+ activeHistoryIndex: 0,
46
57
  };
47
58
  }
@@ -11,6 +11,8 @@ const DOCS_HOSTS = new Set([
11
11
  ]);
12
12
 
13
13
  export const DOCS_DEFAULT_BASE_URL = `https://${DOCS_PRIMARY_DOMAIN}`;
14
+ export const DOC_BROWSER_HOME_TAB_KIND = 'home';
15
+ export const DOC_BROWSER_HOME_URL = 'nextclaw://new-tab';
14
16
  const DOCS_DEFAULT_GUIDE_PATH = '/guide/getting-started';
15
17
 
16
18
  function toDocsLocale(language: I18nLanguage): 'en' | 'zh' {
@@ -358,6 +358,7 @@ export type PanelAppEntryView = {
358
358
  description?: string;
359
359
  icon?: string;
360
360
  contentPath: string;
361
+ createdAt: string;
361
362
  updatedAt: string;
362
363
  sizeBytes: number;
363
364
  favorite: boolean;
@@ -7,7 +7,10 @@ export const DOC_BROWSER_LABELS = {
7
7
  docBrowserDockMode: { zh: '固定到侧栏', en: 'Dock to Sidebar' },
8
8
  docBrowserClose: { zh: '关闭', en: 'Close' },
9
9
  docBrowserHelp: { zh: '帮助文档', en: 'Help Docs' },
10
+ docBrowserBack: { zh: '后退', en: 'Back' },
11
+ docBrowserForward: { zh: '前进', en: 'Forward' },
10
12
  docBrowserNewTab: { zh: '新建标签', en: 'New Tab' },
13
+ docBrowserHomeTitle: { zh: '导航页', en: 'Start Page' },
11
14
  docBrowserCloseTab: { zh: '关闭标签', en: 'Close Tab' },
12
15
  docBrowserTabUntitled: { zh: '未命名', en: 'Untitled' },
13
16
  appsTitle: { zh: '应用', en: 'Apps' },
@@ -25,6 +28,13 @@ export const DOC_BROWSER_LABELS = {
25
28
  panelAppsSortName: { zh: '名称', en: 'Name' },
26
29
  panelAppsFavorite: { zh: '收藏面板应用', en: 'Favorite panel app' },
27
30
  panelAppsUnfavorite: { zh: '取消收藏面板应用', en: 'Unfavorite panel app' },
31
+ panelAppsMoreActions: { zh: '更多面板应用操作', en: 'More panel app actions' },
32
+ panelAppsDelete: { zh: '删除面板应用', en: 'Delete panel app' },
33
+ panelAppsDeleteConfirmTitle: { zh: '删除面板应用?', en: 'Delete panel app?' },
34
+ panelAppsDeleteConfirmDescription: {
35
+ zh: '将删除这个面板应用文件,删除后不可恢复。',
36
+ en: 'This will delete the panel app file and cannot be undone.',
37
+ },
28
38
  panelAppsLastOpened: { zh: '上次打开', en: 'Last opened' },
29
39
  panelAppsUpdated: { zh: '更新于', en: 'Updated' },
30
40
  serviceAppsTitle: { zh: '服务应用', en: 'Service Apps' },