@nextclaw/ui 0.12.4 → 0.12.6

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 (149) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/dist/assets/ChannelsList-D8p4OlM6.js +8 -0
  3. package/dist/assets/ChatPage-A45t1Rmf.js +58 -0
  4. package/dist/assets/DocBrowser-B2MpsnU9.js +1 -0
  5. package/dist/assets/{DocBrowser-NSzgVKka.js → DocBrowser-Cse_F8Nn.js} +1 -1
  6. package/dist/assets/{DocBrowserContext-DpgVdRgk.js → DocBrowserContext-Bai1WU2H.js} +1 -1
  7. package/dist/assets/{LogoBadge-CHS4YNLw.js → LogoBadge-BdxMPc9v.js} +1 -1
  8. package/dist/assets/MarketplacePage-BNZ3Jx5d.js +1 -0
  9. package/dist/assets/MarketplacePage-BbpAkllU.js +49 -0
  10. package/dist/assets/McpMarketplacePage-CxPFOgxv.js +40 -0
  11. package/dist/assets/ModelConfig-3GLqQ5GY.js +1 -0
  12. package/dist/assets/ProviderScopedModelInput-BYNouw-i.js +1 -0
  13. package/dist/assets/ProvidersList-BR1gJ4Dm.js +1 -0
  14. package/dist/assets/{RemoteAccessPage-yfbrveNQ.js → RemoteAccessPage-DyYVWsyK.js} +1 -1
  15. package/dist/assets/RuntimeConfig-ChdfK4Y_.js +1 -0
  16. package/dist/assets/SearchConfig-DTeJvp8m.js +1 -0
  17. package/dist/assets/{SecretsConfig-CLFSSoTl.js → SecretsConfig-CCYO6NcV.js} +2 -2
  18. package/dist/assets/SessionsConfig-Du39vDgt.js +2 -0
  19. package/dist/assets/app-query-client-Dr5d-K8d.js +1 -0
  20. package/dist/assets/{book-open-C7TAghTk.js → book-open-Da4OEPqB.js} +1 -1
  21. package/dist/assets/chat-session-display-CAlPrnlV.js +1 -0
  22. package/dist/assets/{chunk-JZWAC4HX-DbL4EmiT.js → chunk-JZWAC4HX-CoFVxHXV.js} +1 -1
  23. package/dist/assets/client-CSk58DcF.js +7 -0
  24. package/dist/assets/config-D8KzikVB.js +1 -0
  25. package/dist/assets/{createLucideIcon-BRLFtf-8.js → createLucideIcon-83gaZMtv.js} +1 -1
  26. package/dist/assets/desktop-update-config-CfoVwf-w.js +1 -0
  27. package/dist/assets/dist-aTmhMDVh.js +9 -0
  28. package/dist/assets/{dist-DP-JKR4G.js → dist-toEYs-MZ.js} +1 -1
  29. package/dist/assets/{external-link-BkJkiWbH.js → external-link-QQ0TC6X4.js} +1 -1
  30. package/dist/assets/{hash-CbP6-6R9.js → hash-DaFBEkmi.js} +1 -1
  31. package/dist/assets/i18n-C3jb83S6.js +1 -0
  32. package/dist/assets/index-CE4N7ItL.css +1 -0
  33. package/dist/assets/index-riX7Sg0_.js +6 -0
  34. package/dist/assets/infiniteQueryBehavior-BmHX_ayZ.js +1 -0
  35. package/dist/assets/loader-circle-BjMg63eu.js +1 -0
  36. package/dist/assets/{logos-N3dbS6-I.js → logos-Dzlz30M3.js} +1 -1
  37. package/dist/assets/{page-layout-DyuvlNrg.js → page-layout-D2eRufRQ.js} +1 -1
  38. package/dist/assets/plus-CIXME2pD.js +1 -0
  39. package/dist/assets/{popover-BKKWGUaG.js → popover-BSXxm5bj.js} +1 -1
  40. package/dist/assets/{refresh-ccw-BGMdiNGq.js → refresh-ccw-B3zMtN-_.js} +1 -1
  41. package/dist/assets/refresh-cw-DlZkIHnJ.js +1 -0
  42. package/dist/assets/{save-Dh4GQzzX.js → save-Us9fg4Sj.js} +1 -1
  43. package/dist/assets/search-B_Qr0f6C.js +1 -0
  44. package/dist/assets/security-config-BGWYwxNr.js +1 -0
  45. package/dist/assets/{select-BtIi5fnh.js → select-DLYqySQK.js} +1 -1
  46. package/dist/assets/skeleton-CYQJazv6.js +1 -0
  47. package/dist/assets/{status-dot-C4O-2jZP.js → status-dot-DGayudyB.js} +1 -1
  48. package/dist/assets/{switch-DPegGIa_.js → switch-Dz2ScsKx.js} +1 -1
  49. package/dist/assets/{tabs-custom-x5GZexrF.js → tabs-custom-CdKyjiGk.js} +1 -1
  50. package/dist/assets/{trash-2-CU3LYIpQ.js → trash-2-Db-mZOZs.js} +1 -1
  51. package/dist/assets/use-infinite-scroll-loader-DBJX5hj0.js +1 -0
  52. package/dist/assets/{useConfirmDialog-S5WsGOGf.js → useConfirmDialog-DL0a-oGC.js} +1 -1
  53. package/dist/assets/useMutation-BdZm-9PL.js +1 -0
  54. package/dist/assets/x-B8Tho_xC.js +1 -0
  55. package/dist/index.html +20 -18
  56. package/package.json +6 -6
  57. package/src/App.tsx +2 -0
  58. package/src/account/components/account-panel.tsx +46 -4
  59. package/src/account/managers/account.manager.ts +19 -4
  60. package/src/api/raw-client.test.ts +37 -0
  61. package/src/api/raw-client.ts +51 -8
  62. package/src/api/remote.ts +9 -0
  63. package/src/api/remote.types.ts +5 -0
  64. package/src/components/chat/ChatConversationPanel.test.tsx +344 -142
  65. package/src/components/chat/ChatSidebar.test.tsx +109 -4
  66. package/src/components/chat/ChatSidebar.tsx +62 -9
  67. package/src/components/chat/adapters/chat-message-tool-agent-id.test.ts +11 -11
  68. package/src/components/chat/adapters/chat-message.adapter.test.ts +43 -6
  69. package/src/components/chat/adapters/chat-message.session-request-tool-card.ts +182 -44
  70. package/src/components/chat/adapters/chat-message.session-spawn-tool-card.test.ts +104 -0
  71. package/src/components/chat/chat-child-session-panel.tsx +155 -59
  72. package/src/components/chat/chat-page-runtime.test.ts +16 -19
  73. package/src/components/chat/chat-session-preference-sync.test.ts +13 -0
  74. package/src/components/chat/chat-session-preference-sync.ts +9 -7
  75. package/src/components/chat/chat-sidebar-session-item.tsx +189 -121
  76. package/src/components/chat/containers/chat-message-list.container.test.tsx +21 -3
  77. package/src/components/chat/containers/chat-message-list.container.tsx +14 -0
  78. package/src/components/chat/hooks/use-chat-session-project.test.tsx +5 -5
  79. package/src/components/chat/hooks/use-chat-session-project.ts +0 -5
  80. package/src/components/chat/hooks/use-chat-session-update.test.tsx +75 -0
  81. package/src/components/chat/hooks/use-chat-session-update.ts +4 -2
  82. package/src/components/chat/managers/chat-session-list.manager.test.ts +79 -5
  83. package/src/components/chat/managers/chat-session-list.manager.ts +31 -4
  84. package/src/components/chat/ncp/NcpChatPage.tsx +32 -51
  85. package/src/components/chat/ncp/ncp-app-client-fetch.test.ts +1 -1
  86. package/src/components/chat/ncp/ncp-app-client-fetch.ts +45 -5
  87. package/src/components/chat/ncp/ncp-chat-input.manager.ts +3 -5
  88. package/src/components/chat/ncp/ncp-chat-page-data.ts +0 -1
  89. package/src/components/chat/ncp/ncp-chat.presenter.ts +1 -11
  90. package/src/components/chat/ncp/session-conversation/use-ncp-child-session-tabs-view.ts +35 -9
  91. package/src/components/chat/stores/chat-session-list.store.ts +99 -5
  92. package/src/components/chat/useChatSessionTypeState.test.tsx +0 -3
  93. package/src/components/chat/useChatSessionTypeState.ts +3 -5
  94. package/src/components/config/ChannelsList.test.tsx +68 -0
  95. package/src/components/config/ChannelsList.tsx +22 -4
  96. package/src/components/config/ProviderForm.tsx +9 -15
  97. package/src/components/config/ProvidersList.tsx +17 -3
  98. package/src/components/config/desktop-update-config.tsx +230 -0
  99. package/src/components/config/providers-list.test.tsx +68 -0
  100. package/src/components/layout/Sidebar.tsx +19 -14
  101. package/src/components/layout/sidebar.layout.test.tsx +33 -1
  102. package/src/components/marketplace/MarketplacePage.tsx +30 -30
  103. package/src/components/marketplace/marketplace-page-parts.tsx +16 -24
  104. package/src/components/marketplace/mcp/McpMarketplacePage.tsx +28 -26
  105. package/src/desktop/desktop-update.types.ts +36 -0
  106. package/src/desktop/managers/desktop-update.manager.ts +163 -0
  107. package/src/desktop/stores/desktop-update.store.ts +18 -0
  108. package/src/hooks/marketplace-list-pages.ts +27 -0
  109. package/src/hooks/use-infinite-scroll-loader.ts +88 -0
  110. package/src/hooks/useMarketplace.ts +14 -3
  111. package/src/hooks/useMcpMarketplace.ts +14 -3
  112. package/src/lib/desktop-update-labels.utils.ts +72 -0
  113. package/src/lib/i18n.chat.ts +13 -0
  114. package/src/lib/i18n.remote.ts +15 -0
  115. package/src/lib/i18n.ts +3 -9
  116. package/src/lib/ui-document-title.ts +1 -0
  117. package/src/transport/local.transport.ts +57 -18
  118. package/src/vite-env.d.ts +10 -0
  119. package/dist/assets/ChannelsList-CobWeI2V.js +0 -8
  120. package/dist/assets/ChatPage-ZIdFFVAv.js +0 -43
  121. package/dist/assets/DocBrowser-D55C0iyl.js +0 -1
  122. package/dist/assets/MarketplacePage-BFYsRss_.js +0 -49
  123. package/dist/assets/MarketplacePage-DII-q-Y1.js +0 -1
  124. package/dist/assets/McpMarketplacePage-CPqsGJzz.js +0 -40
  125. package/dist/assets/ModelConfig-Bvuo_IpS.js +0 -1
  126. package/dist/assets/ProviderScopedModelInput-BfY8rGsf.js +0 -1
  127. package/dist/assets/ProvidersList-3tlaqwSS.js +0 -1
  128. package/dist/assets/RuntimeConfig-CAd5Kta3.js +0 -1
  129. package/dist/assets/SearchConfig-DFwgaAa7.js +0 -1
  130. package/dist/assets/SessionsConfig-vYrvc2Fk.js +0 -2
  131. package/dist/assets/chat-session-display-5dVFkJyw.js +0 -1
  132. package/dist/assets/config-CMiW0yaK.js +0 -1
  133. package/dist/assets/dist-BFc_H-lY.js +0 -15
  134. package/dist/assets/i18n-C_2dKw6w.js +0 -1
  135. package/dist/assets/index-ChUXhq0G.css +0 -1
  136. package/dist/assets/index-DAE8Srx-.js +0 -6
  137. package/dist/assets/label-D8yyejJS.js +0 -1
  138. package/dist/assets/loader-circle-B0sKKO29.js +0 -1
  139. package/dist/assets/marketplace-localization-CxSTG9wr.js +0 -1
  140. package/dist/assets/plus-CYXs3JtZ.js +0 -1
  141. package/dist/assets/react-8EIEQjMP.js +0 -1
  142. package/dist/assets/search-DOsLw-P9.js +0 -1
  143. package/dist/assets/security-config-CM_tQRXQ.js +0 -1
  144. package/dist/assets/skeleton-GbHLjPC0.js +0 -1
  145. package/dist/assets/useMutation-DSinpgEq.js +0 -1
  146. package/dist/assets/x-Bnco_K8b.js +0 -1
  147. package/src/components/chat/ChatSessionsSidebar.tsx +0 -100
  148. /package/dist/assets/{config-hints-WtpHP_DW.js → config-hints-GSUMvmSo.js} +0 -0
  149. /package/dist/assets/{config-layout-LQ10ozRC.js → config-layout-CgBMG7OL.js} +0 -0
@@ -1,4 +1,4 @@
1
- import { logoutRemote, pollRemoteBrowserAuth, startRemoteBrowserAuth } from '@/api/remote';
1
+ import { logoutRemote, pollRemoteBrowserAuth, startRemoteBrowserAuth, updateRemoteAccountProfile } from '@/api/remote';
2
2
  import type { RemoteAccessView } from '@/api/remote.types';
3
3
  import type { AccountPendingAction } from '@/account/stores/account.store';
4
4
  import { useAccountStore } from '@/account/stores/account.store';
@@ -57,12 +57,14 @@ export class AccountManager {
57
57
  pendingAction?: AccountPendingAction;
58
58
  }) => {
59
59
  try {
60
+ const apiBase = params?.apiBase;
61
+ const pendingAction = params?.pendingAction;
60
62
  const status = params?.status ?? (await ensureRemoteStatus());
61
- if (params?.pendingAction) {
62
- useAccountStore.getState().setPendingAction(params.pendingAction);
63
+ if (pendingAction) {
64
+ useAccountStore.getState().setPendingAction(pendingAction);
63
65
  }
64
66
  const result = await startRemoteBrowserAuth({
65
- apiBase: resolveRemotePlatformApiBase(status, params?.apiBase)
67
+ apiBase: resolveRemotePlatformApiBase(status, apiBase)
66
68
  });
67
69
  useAccountStore.getState().beginBrowserAuth({
68
70
  sessionId: result.sessionId,
@@ -103,6 +105,19 @@ export class AccountManager {
103
105
  }
104
106
  };
105
107
 
108
+ updateUsername = async (username: string) => {
109
+ try {
110
+ await updateRemoteAccountProfile({
111
+ username: username.trim()
112
+ });
113
+ await refreshRemoteStatus();
114
+ toast.success(t('remoteAccountUsernameSetSuccess'));
115
+ } catch (error) {
116
+ const message = error instanceof Error ? error.message : t('remoteAccountUsernameSetFailed');
117
+ toast.error(`${t('remoteAccountUsernameSetFailed')}: ${message}`);
118
+ }
119
+ };
120
+
106
121
  openNextClawWeb = async () => {
107
122
  const status = await ensureRemoteStatus();
108
123
  const webBase = resolveRemoteWebBase(status);
@@ -0,0 +1,37 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
2
+ import { requestRawApiResponse } from './raw-client';
3
+
4
+ const fetchMock = vi.fn<typeof fetch>();
5
+
6
+ describe('requestRawApiResponse', () => {
7
+ beforeEach(() => {
8
+ fetchMock.mockReset();
9
+ vi.stubGlobal('fetch', fetchMock);
10
+ });
11
+
12
+ afterEach(() => {
13
+ vi.unstubAllGlobals();
14
+ });
15
+
16
+ it('preserves original fetch failure details in synthetic network errors', async () => {
17
+ fetchMock.mockRejectedValue(new TypeError('Failed to fetch'));
18
+
19
+ const response = await requestRawApiResponse('/api/config', {
20
+ method: 'POST'
21
+ });
22
+
23
+ expect(response.ok).toBe(false);
24
+ if (response.ok) {
25
+ throw new Error('expected synthetic error response');
26
+ }
27
+ expect(response.error.code).toBe('NETWORK_ERROR');
28
+ expect(response.error.message).toContain('Fetch failed on POST /api/config');
29
+ expect(response.error.message).toContain('TypeError: Failed to fetch');
30
+ expect(response.error.details).toMatchObject({
31
+ method: 'POST',
32
+ endpoint: '/api/config',
33
+ errorName: 'TypeError',
34
+ errorMessage: 'Failed to fetch'
35
+ });
36
+ });
37
+ });
@@ -25,6 +25,31 @@ function inferNonJsonHint(endpoint: string, status: number): string | undefined
25
25
  return undefined;
26
26
  }
27
27
 
28
+ function formatUnknownFetchError(error: unknown): {
29
+ summary: string;
30
+ details: Record<string, unknown>;
31
+ } {
32
+ if (error instanceof Error) {
33
+ const name = error.name?.trim() || 'Error';
34
+ const message = error.message?.trim() || 'Unknown error';
35
+ return {
36
+ summary: `${name}: ${message}`,
37
+ details: {
38
+ errorName: name,
39
+ errorMessage: message,
40
+ ...(error.stack?.trim() ? { errorStack: error.stack.trim() } : {})
41
+ }
42
+ };
43
+ }
44
+ return {
45
+ summary: String(error ?? 'Unknown error'),
46
+ details: {
47
+ errorName: 'NonError',
48
+ errorMessage: String(error ?? 'Unknown error')
49
+ }
50
+ };
51
+ }
52
+
28
53
  export async function requestRawApiResponse<T>(
29
54
  endpoint: string,
30
55
  options: RequestInit = {}
@@ -32,14 +57,32 @@ export async function requestRawApiResponse<T>(
32
57
  const url = `${API_BASE}${endpoint}`;
33
58
  const method = (options.method || 'GET').toUpperCase();
34
59
 
35
- const response = await fetch(url, {
36
- credentials: 'include',
37
- headers: {
38
- 'Content-Type': 'application/json',
39
- ...options.headers
40
- },
41
- ...options
42
- });
60
+ let response: Response;
61
+ try {
62
+ response = await fetch(url, {
63
+ credentials: 'include',
64
+ headers: {
65
+ 'Content-Type': 'application/json',
66
+ ...options.headers
67
+ },
68
+ ...options
69
+ });
70
+ } catch (error) {
71
+ const formatted = formatUnknownFetchError(error);
72
+ return {
73
+ ok: false,
74
+ error: {
75
+ code: 'NETWORK_ERROR',
76
+ message: `Fetch failed on ${method} ${endpoint} | ${formatted.summary}`,
77
+ details: {
78
+ method,
79
+ endpoint,
80
+ url,
81
+ ...formatted.details
82
+ }
83
+ }
84
+ };
85
+ }
43
86
 
44
87
  const text = await response.text();
45
88
  let data: ApiResponse<T> | null = null;
package/src/api/remote.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { api } from './client';
2
2
  import type {
3
3
  RemoteAccessView,
4
+ RemoteAccountProfileUpdateRequest,
4
5
  RemoteBrowserAuthPollRequest,
5
6
  RemoteBrowserAuthPollResult,
6
7
  RemoteBrowserAuthStartRequest,
@@ -60,6 +61,14 @@ export async function logoutRemote(): Promise<RemoteAccessView> {
60
61
  return response.data;
61
62
  }
62
63
 
64
+ export async function updateRemoteAccountProfile(data: RemoteAccountProfileUpdateRequest): Promise<RemoteAccessView> {
65
+ const response = await api.put<RemoteAccessView>('/api/remote/account/profile', data);
66
+ if (!response.ok) {
67
+ throw new Error(response.error.message);
68
+ }
69
+ return response.data;
70
+ }
71
+
63
72
  export async function updateRemoteSettings(data: RemoteSettingsUpdateRequest): Promise<RemoteAccessView> {
64
73
  const response = await api.put<RemoteAccessView>('/api/remote/settings', data);
65
74
  if (!response.ok) {
@@ -1,11 +1,16 @@
1
1
  export type RemoteAccountView = {
2
2
  loggedIn: boolean;
3
3
  email?: string;
4
+ username?: string | null;
4
5
  role?: string;
5
6
  platformBase?: string | null;
6
7
  apiBase?: string | null;
7
8
  };
8
9
 
10
+ export type RemoteAccountProfileUpdateRequest = {
11
+ username: string;
12
+ };
13
+
9
14
  export type RemoteRuntimeView = {
10
15
  enabled: boolean;
11
16
  mode: "service" | "foreground";