@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.
- package/CHANGELOG.md +66 -0
- package/dist/assets/ChannelsList-D8p4OlM6.js +8 -0
- package/dist/assets/ChatPage-A45t1Rmf.js +58 -0
- package/dist/assets/DocBrowser-B2MpsnU9.js +1 -0
- package/dist/assets/{DocBrowser-NSzgVKka.js → DocBrowser-Cse_F8Nn.js} +1 -1
- package/dist/assets/{DocBrowserContext-DpgVdRgk.js → DocBrowserContext-Bai1WU2H.js} +1 -1
- package/dist/assets/{LogoBadge-CHS4YNLw.js → LogoBadge-BdxMPc9v.js} +1 -1
- package/dist/assets/MarketplacePage-BNZ3Jx5d.js +1 -0
- package/dist/assets/MarketplacePage-BbpAkllU.js +49 -0
- package/dist/assets/McpMarketplacePage-CxPFOgxv.js +40 -0
- package/dist/assets/ModelConfig-3GLqQ5GY.js +1 -0
- package/dist/assets/ProviderScopedModelInput-BYNouw-i.js +1 -0
- package/dist/assets/ProvidersList-BR1gJ4Dm.js +1 -0
- package/dist/assets/{RemoteAccessPage-yfbrveNQ.js → RemoteAccessPage-DyYVWsyK.js} +1 -1
- package/dist/assets/RuntimeConfig-ChdfK4Y_.js +1 -0
- package/dist/assets/SearchConfig-DTeJvp8m.js +1 -0
- package/dist/assets/{SecretsConfig-CLFSSoTl.js → SecretsConfig-CCYO6NcV.js} +2 -2
- package/dist/assets/SessionsConfig-Du39vDgt.js +2 -0
- package/dist/assets/app-query-client-Dr5d-K8d.js +1 -0
- package/dist/assets/{book-open-C7TAghTk.js → book-open-Da4OEPqB.js} +1 -1
- package/dist/assets/chat-session-display-CAlPrnlV.js +1 -0
- package/dist/assets/{chunk-JZWAC4HX-DbL4EmiT.js → chunk-JZWAC4HX-CoFVxHXV.js} +1 -1
- package/dist/assets/client-CSk58DcF.js +7 -0
- package/dist/assets/config-D8KzikVB.js +1 -0
- package/dist/assets/{createLucideIcon-BRLFtf-8.js → createLucideIcon-83gaZMtv.js} +1 -1
- package/dist/assets/desktop-update-config-CfoVwf-w.js +1 -0
- package/dist/assets/dist-aTmhMDVh.js +9 -0
- package/dist/assets/{dist-DP-JKR4G.js → dist-toEYs-MZ.js} +1 -1
- package/dist/assets/{external-link-BkJkiWbH.js → external-link-QQ0TC6X4.js} +1 -1
- package/dist/assets/{hash-CbP6-6R9.js → hash-DaFBEkmi.js} +1 -1
- package/dist/assets/i18n-C3jb83S6.js +1 -0
- package/dist/assets/index-CE4N7ItL.css +1 -0
- package/dist/assets/index-riX7Sg0_.js +6 -0
- package/dist/assets/infiniteQueryBehavior-BmHX_ayZ.js +1 -0
- package/dist/assets/loader-circle-BjMg63eu.js +1 -0
- package/dist/assets/{logos-N3dbS6-I.js → logos-Dzlz30M3.js} +1 -1
- package/dist/assets/{page-layout-DyuvlNrg.js → page-layout-D2eRufRQ.js} +1 -1
- package/dist/assets/plus-CIXME2pD.js +1 -0
- package/dist/assets/{popover-BKKWGUaG.js → popover-BSXxm5bj.js} +1 -1
- package/dist/assets/{refresh-ccw-BGMdiNGq.js → refresh-ccw-B3zMtN-_.js} +1 -1
- package/dist/assets/refresh-cw-DlZkIHnJ.js +1 -0
- package/dist/assets/{save-Dh4GQzzX.js → save-Us9fg4Sj.js} +1 -1
- package/dist/assets/search-B_Qr0f6C.js +1 -0
- package/dist/assets/security-config-BGWYwxNr.js +1 -0
- package/dist/assets/{select-BtIi5fnh.js → select-DLYqySQK.js} +1 -1
- package/dist/assets/skeleton-CYQJazv6.js +1 -0
- package/dist/assets/{status-dot-C4O-2jZP.js → status-dot-DGayudyB.js} +1 -1
- package/dist/assets/{switch-DPegGIa_.js → switch-Dz2ScsKx.js} +1 -1
- package/dist/assets/{tabs-custom-x5GZexrF.js → tabs-custom-CdKyjiGk.js} +1 -1
- package/dist/assets/{trash-2-CU3LYIpQ.js → trash-2-Db-mZOZs.js} +1 -1
- package/dist/assets/use-infinite-scroll-loader-DBJX5hj0.js +1 -0
- package/dist/assets/{useConfirmDialog-S5WsGOGf.js → useConfirmDialog-DL0a-oGC.js} +1 -1
- package/dist/assets/useMutation-BdZm-9PL.js +1 -0
- package/dist/assets/x-B8Tho_xC.js +1 -0
- package/dist/index.html +20 -18
- package/package.json +6 -6
- package/src/App.tsx +2 -0
- package/src/account/components/account-panel.tsx +46 -4
- package/src/account/managers/account.manager.ts +19 -4
- package/src/api/raw-client.test.ts +37 -0
- package/src/api/raw-client.ts +51 -8
- package/src/api/remote.ts +9 -0
- package/src/api/remote.types.ts +5 -0
- package/src/components/chat/ChatConversationPanel.test.tsx +344 -142
- package/src/components/chat/ChatSidebar.test.tsx +109 -4
- package/src/components/chat/ChatSidebar.tsx +62 -9
- package/src/components/chat/adapters/chat-message-tool-agent-id.test.ts +11 -11
- package/src/components/chat/adapters/chat-message.adapter.test.ts +43 -6
- package/src/components/chat/adapters/chat-message.session-request-tool-card.ts +182 -44
- package/src/components/chat/adapters/chat-message.session-spawn-tool-card.test.ts +104 -0
- package/src/components/chat/chat-child-session-panel.tsx +155 -59
- package/src/components/chat/chat-page-runtime.test.ts +16 -19
- package/src/components/chat/chat-session-preference-sync.test.ts +13 -0
- package/src/components/chat/chat-session-preference-sync.ts +9 -7
- package/src/components/chat/chat-sidebar-session-item.tsx +189 -121
- package/src/components/chat/containers/chat-message-list.container.test.tsx +21 -3
- package/src/components/chat/containers/chat-message-list.container.tsx +14 -0
- package/src/components/chat/hooks/use-chat-session-project.test.tsx +5 -5
- package/src/components/chat/hooks/use-chat-session-project.ts +0 -5
- package/src/components/chat/hooks/use-chat-session-update.test.tsx +75 -0
- package/src/components/chat/hooks/use-chat-session-update.ts +4 -2
- package/src/components/chat/managers/chat-session-list.manager.test.ts +79 -5
- package/src/components/chat/managers/chat-session-list.manager.ts +31 -4
- package/src/components/chat/ncp/NcpChatPage.tsx +32 -51
- package/src/components/chat/ncp/ncp-app-client-fetch.test.ts +1 -1
- package/src/components/chat/ncp/ncp-app-client-fetch.ts +45 -5
- package/src/components/chat/ncp/ncp-chat-input.manager.ts +3 -5
- package/src/components/chat/ncp/ncp-chat-page-data.ts +0 -1
- package/src/components/chat/ncp/ncp-chat.presenter.ts +1 -11
- package/src/components/chat/ncp/session-conversation/use-ncp-child-session-tabs-view.ts +35 -9
- package/src/components/chat/stores/chat-session-list.store.ts +99 -5
- package/src/components/chat/useChatSessionTypeState.test.tsx +0 -3
- package/src/components/chat/useChatSessionTypeState.ts +3 -5
- package/src/components/config/ChannelsList.test.tsx +68 -0
- package/src/components/config/ChannelsList.tsx +22 -4
- package/src/components/config/ProviderForm.tsx +9 -15
- package/src/components/config/ProvidersList.tsx +17 -3
- package/src/components/config/desktop-update-config.tsx +230 -0
- package/src/components/config/providers-list.test.tsx +68 -0
- package/src/components/layout/Sidebar.tsx +19 -14
- package/src/components/layout/sidebar.layout.test.tsx +33 -1
- package/src/components/marketplace/MarketplacePage.tsx +30 -30
- package/src/components/marketplace/marketplace-page-parts.tsx +16 -24
- package/src/components/marketplace/mcp/McpMarketplacePage.tsx +28 -26
- package/src/desktop/desktop-update.types.ts +36 -0
- package/src/desktop/managers/desktop-update.manager.ts +163 -0
- package/src/desktop/stores/desktop-update.store.ts +18 -0
- package/src/hooks/marketplace-list-pages.ts +27 -0
- package/src/hooks/use-infinite-scroll-loader.ts +88 -0
- package/src/hooks/useMarketplace.ts +14 -3
- package/src/hooks/useMcpMarketplace.ts +14 -3
- package/src/lib/desktop-update-labels.utils.ts +72 -0
- package/src/lib/i18n.chat.ts +13 -0
- package/src/lib/i18n.remote.ts +15 -0
- package/src/lib/i18n.ts +3 -9
- package/src/lib/ui-document-title.ts +1 -0
- package/src/transport/local.transport.ts +57 -18
- package/src/vite-env.d.ts +10 -0
- package/dist/assets/ChannelsList-CobWeI2V.js +0 -8
- package/dist/assets/ChatPage-ZIdFFVAv.js +0 -43
- package/dist/assets/DocBrowser-D55C0iyl.js +0 -1
- package/dist/assets/MarketplacePage-BFYsRss_.js +0 -49
- package/dist/assets/MarketplacePage-DII-q-Y1.js +0 -1
- package/dist/assets/McpMarketplacePage-CPqsGJzz.js +0 -40
- package/dist/assets/ModelConfig-Bvuo_IpS.js +0 -1
- package/dist/assets/ProviderScopedModelInput-BfY8rGsf.js +0 -1
- package/dist/assets/ProvidersList-3tlaqwSS.js +0 -1
- package/dist/assets/RuntimeConfig-CAd5Kta3.js +0 -1
- package/dist/assets/SearchConfig-DFwgaAa7.js +0 -1
- package/dist/assets/SessionsConfig-vYrvc2Fk.js +0 -2
- package/dist/assets/chat-session-display-5dVFkJyw.js +0 -1
- package/dist/assets/config-CMiW0yaK.js +0 -1
- package/dist/assets/dist-BFc_H-lY.js +0 -15
- package/dist/assets/i18n-C_2dKw6w.js +0 -1
- package/dist/assets/index-ChUXhq0G.css +0 -1
- package/dist/assets/index-DAE8Srx-.js +0 -6
- package/dist/assets/label-D8yyejJS.js +0 -1
- package/dist/assets/loader-circle-B0sKKO29.js +0 -1
- package/dist/assets/marketplace-localization-CxSTG9wr.js +0 -1
- package/dist/assets/plus-CYXs3JtZ.js +0 -1
- package/dist/assets/react-8EIEQjMP.js +0 -1
- package/dist/assets/search-DOsLw-P9.js +0 -1
- package/dist/assets/security-config-CM_tQRXQ.js +0 -1
- package/dist/assets/skeleton-GbHLjPC0.js +0 -1
- package/dist/assets/useMutation-DSinpgEq.js +0 -1
- package/dist/assets/x-Bnco_K8b.js +0 -1
- package/src/components/chat/ChatSessionsSidebar.tsx +0 -100
- /package/dist/assets/{config-hints-WtpHP_DW.js → config-hints-GSUMvmSo.js} +0 -0
- /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 (
|
|
62
|
-
useAccountStore.getState().setPendingAction(
|
|
63
|
+
if (pendingAction) {
|
|
64
|
+
useAccountStore.getState().setPendingAction(pendingAction);
|
|
63
65
|
}
|
|
64
66
|
const result = await startRemoteBrowserAuth({
|
|
65
|
-
apiBase: resolveRemotePlatformApiBase(status,
|
|
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
|
+
});
|
package/src/api/raw-client.ts
CHANGED
|
@@ -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
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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) {
|
package/src/api/remote.types.ts
CHANGED
|
@@ -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";
|