@nextclaw/ui 0.24.2 → 0.25.0
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 +43 -0
- package/dist/.vite/manifest.json +538 -525
- package/dist/assets/{account-panel-BxMlLXYH.js → account-panel-UvHFa8Kl.js} +1 -1
- package/dist/assets/{api-Utt-xzrT.js → api-Dffeij78.js} +5 -5
- package/dist/assets/{app-data-DYXDL6X2.js → app-data-DzaIMy4D.js} +1 -1
- package/dist/assets/app-presenter-provider-O2tUKKGf.js +109 -0
- package/dist/assets/{appearance-settings-page-BfYznAK5.js → appearance-settings-page-D8cWniw-.js} +1 -1
- package/dist/assets/{book-open-DDW_3XpM.js → book-open-xqEj1OLE.js} +1 -1
- package/dist/assets/{boxes-DwJeuK_h.js → boxes-D6uPnkGo.js} +1 -1
- package/dist/assets/{card-IevY2nm-.js → card-CS8su2Zh.js} +1 -1
- package/dist/assets/{channels-list-page-DitnqbMR.js → channels-list-page-B_fYP1Pn.js} +1 -1
- package/dist/assets/{chevron-down-An7Km-t4.js → chevron-down-BL-yMYcX.js} +1 -1
- package/dist/assets/{circle-alert-CDXqELuo.js → circle-alert-lSa3LRvS.js} +1 -1
- package/dist/assets/{circle-dashed-CapXEpiV.js → circle-dashed-CU3yApvP.js} +1 -1
- package/dist/assets/{client-B0krol7A.js → client-BtGBwLTs.js} +1 -1
- package/dist/assets/{config-split-page-BtnkqWVp.js → config-split-page-6hHiiapl.js} +1 -1
- package/dist/assets/{confirm-dialog-DFt4jpN7.js → confirm-dialog-ClT6iaj8.js} +1 -1
- package/dist/assets/{createLucideIcon-BTHK0Ot9.js → createLucideIcon-BNKf0_kc.js} +1 -1
- package/dist/assets/{desktop-capabilities-page-CCf14WId.js → desktop-capabilities-page-CB5pniTx.js} +1 -1
- package/dist/assets/{desktop-update-config-DVoVgfFi.js → desktop-update-config-OuQV73gg.js} +1 -1
- package/dist/assets/{dialog-BFN_1DBH.js → dialog-Xe73hpQz.js} +1 -1
- package/dist/assets/{dist-Bc9hOVNN.js → dist-BiIcnf9j.js} +1 -1
- package/dist/assets/{dist-CEhIDAnr.js → dist-C5I0v8Qn.js} +1 -1
- package/dist/assets/{dist-hkVPP1th.js → dist-czPa8xFO.js} +1 -1
- package/dist/assets/doc-browser-BFkslEzY.js +1 -0
- package/dist/assets/{doc-browser-BNUxmwD6.js → doc-browser-Cu58uiEg.js} +1 -1
- package/dist/assets/{doc-browser-context-C4yQrKrH.js → doc-browser-context-CekJxJFm.js} +1 -1
- package/dist/assets/{ellipsis-BRI6ROeu.js → ellipsis-C5YXdOUx.js} +1 -1
- package/dist/assets/{es2015-MOCbM0Eu.js → es2015-cuwbYI-l.js} +1 -1
- package/dist/assets/{extensions-DxUBMtHW.js → extensions-B5r-0jCq.js} +1 -1
- package/dist/assets/{eye-cnynUDGt.js → eye-C84inPcV.js} +1 -1
- package/dist/assets/{form-actions-gQ0JEUwB.js → form-actions-AIdXOoCL.js} +1 -1
- package/dist/assets/{i18n-B9yXA8KO.js → i18n-CPjq_hQX.js} +2 -2
- package/dist/assets/{i18n-provider-BYBJua91.js → i18n-provider-BYO9AhFy.js} +1 -1
- package/dist/assets/keyboard-shortcuts-settings-page-1efEkGwq.js +1 -0
- package/dist/assets/loader-circle-K1BDdHR5.js +1 -0
- package/dist/assets/{login-page-CqrHhzaN.js → login-page-DBqkVTVD.js} +1 -1
- package/dist/assets/login-page-DjcRQLQe.js +1 -0
- package/dist/assets/{logo-badge-Cr03YceJ.js → logo-badge-C-5-zim6.js} +1 -1
- package/dist/assets/main-CLwCjK9U.css +1 -0
- package/dist/assets/main-CQ6GUYdX.js +2 -0
- package/dist/assets/main-i18n-catalog.config-QB4DfJRJ.js +1 -0
- package/dist/assets/{mcp-marketplace-page-CifiVgFD.js → mcp-marketplace-page-CWAxBNaS.js} +1 -1
- package/dist/assets/mcp-marketplace-page-Ct090ceA.js +1 -0
- package/dist/assets/{model-config-page-C6jVNbSj.js → model-config-page-DBcuZyRC.js} +1 -1
- package/dist/assets/{navigation-link-kbCLRSr_.js → navigation-link-BAQjgx2F.js} +1 -1
- package/dist/assets/panel-app-i18n-catalog.config-CQFujXqt.js +1 -0
- package/dist/assets/panel-app-maumVhbl.js +1 -0
- package/dist/assets/{panelStandalone-DMBnYyTw.js → panelStandalone-BGA1s7JG.js} +2 -2
- package/dist/assets/plus-LA8-jpxP.js +1 -0
- package/dist/assets/{popover-XVDgjxcl.js → popover-NkrFlWHp.js} +1 -1
- package/dist/assets/{privacy-settings-page-BN27MBVA.js → privacy-settings-page-DVC-aq1v.js} +1 -1
- package/dist/assets/projects-Cq0E3c7N.js +1 -0
- package/dist/assets/{provider-scoped-model-input-BGZMCThn.js → provider-scoped-model-input-BGdZMWWa.js} +1 -1
- package/dist/assets/{providers-config-page-D5aBwbOD.js → providers-config-page-B-IhHl6x.js} +1 -1
- package/dist/assets/{puzzle-D5Dhacmb.js → puzzle-D6gulz7u.js} +1 -1
- package/dist/assets/{pwa-ClQK56Qe.js → pwa-C3kR9mdy.js} +1 -1
- package/dist/assets/{refresh-cw-Bw5BY7vp.js → refresh-cw-h9Xq3LY3.js} +1 -1
- package/dist/assets/remote-Cnawibbg.js +1 -0
- package/dist/assets/{rotate-cw-BksCLAeE.js → rotate-cw-B6xm41Wn.js} +1 -1
- package/dist/assets/runtime-config-page-LmrB2q65.js +1 -0
- package/dist/assets/{save-CVi8VWzb.js → save-fff_WpY2.js} +1 -1
- package/dist/assets/{search-DN-f7IIC.js → search-CUe41wjm.js} +1 -1
- package/dist/assets/{search-config-page-BmuZTVxs.js → search-config-page-BIXmv5FY.js} +1 -1
- package/dist/assets/{secrets-config-page-NPHpg9sb.js → secrets-config-page-DU3fadrq.js} +1 -1
- package/dist/assets/security-config-9s0i0I4N.js +1 -0
- package/dist/assets/{select-CmDTqk2C.js → select-CG5YWnwe.js} +1 -1
- package/dist/assets/{service-apps-panel-BYGJ9_pO.js → service-apps-panel-Bshf3Wmq.js} +1 -1
- package/dist/assets/{settings-2-B62YtZon.js → settings-2-CE3ELQyk.js} +1 -1
- package/dist/assets/skeleton-BL9h32W7.js +1 -0
- package/dist/assets/{tabs-Bk_mG7ql.js → tabs-BuE0qKMh.js} +1 -1
- package/dist/assets/{tag-chip-DgqKlI5D.js → tag-chip-gAH1IOsZ.js} +1 -1
- package/dist/assets/{theme-provider-CeBY2pyu.js → theme-provider-DE7m9jvf.js} +1 -1
- package/dist/assets/{tooltip-CgGbBdYf.js → tooltip-DYcuWhuP.js} +1 -1
- package/dist/assets/{trash-2-CVOev8yc.js → trash-2-BPPYt2NV.js} +1 -1
- package/dist/assets/{use-config-b2DN67gs.js → use-config-Cyiw06-j.js} +1 -1
- package/dist/assets/{use-desktop-capabilities-B3tLU1yl.js → use-desktop-capabilities-OKG96v4y.js} +1 -1
- package/dist/assets/{use-panel-app-scroll-restoration-BekzoX6z.js → use-panel-app-scroll-restoration-DsV1IJx-.js} +1 -1
- package/dist/assets/{use-viewport-layout-CUA3jQsA.js → use-viewport-layout-BS18drMT.js} +1 -1
- package/dist/assets/{utils-UBHTdG5Q.js → utils-CBZPzC_b.js} +1 -1
- package/dist/assets/x-DdXOqLnX.js +1 -0
- package/dist/index.html +50 -50
- package/dist/panel-standalone.html +15 -15
- package/package.json +7 -7
- package/src/app/configs/app-navigation.config.ts +10 -3
- package/src/app/index.tsx +7 -0
- package/src/features/chat/components/providers/chat-presenter.provider.tsx +2 -0
- package/src/features/chat/features/conversation/components/__tests__/session-conversation-area.test.tsx +12 -0
- package/src/features/chat/features/conversation/components/__tests__/session-conversation-input.streaming.test.tsx +13 -1
- package/src/features/chat/features/conversation/components/__tests__/session-voice-input.test-utils.ts +52 -0
- package/src/features/chat/features/conversation/components/chat-voice-input-panel.tsx +70 -0
- package/src/features/chat/features/conversation/components/chat-voice-shortcut-control.tsx +33 -0
- package/src/features/chat/features/conversation/components/session-conversation-area.tsx +1 -11
- package/src/features/chat/features/conversation/components/session-conversation-input.tsx +29 -5
- package/src/features/chat/features/conversation/hooks/__tests__/use-chat-voice-input.test.tsx +185 -0
- package/src/features/chat/features/conversation/hooks/use-chat-voice-input.ts +52 -0
- package/src/features/chat/features/input/utils/__tests__/chat-input-bar.utils.test.ts +13 -6
- package/src/features/chat/features/input/utils/chat-input-toolbar.utils.ts +28 -12
- package/src/features/chat/features/message/utils/__tests__/chat-message-process-summary.utils.test.ts +19 -1
- package/src/features/chat/features/message/utils/__tests__/chat-message-timeline.utils.test.ts +10 -0
- package/src/features/chat/features/message/utils/__tests__/chat-message.utils.test.ts +7 -6
- package/src/features/chat/features/message/utils/chat-message-part.utils.ts +4 -1
- package/src/features/chat/features/ncp/hooks/__tests__/use-ncp-agent-runtime.test.tsx +20 -0
- package/src/features/chat/features/session/components/__tests__/chat-sidebar-project-groups.test.tsx +90 -6
- package/src/features/chat/features/session/components/chat-sidebar-project-groups.tsx +64 -2
- package/src/features/chat/index.ts +1 -0
- package/src/features/chat/managers/chat-voice-input.manager.ts +174 -0
- package/src/features/chat/presenters/chat.presenter.ts +2 -0
- package/src/features/chat/stores/chat-voice-shortcut.store.ts +31 -0
- package/src/features/desktop-capabilities/index.ts +1 -0
- package/src/features/panel-apps/components/__tests__/panel-app-open-standalone-menu-item.test.tsx +3 -2
- package/src/features/panel-apps/components/panel-app-open-standalone-menu-item.tsx +4 -1
- package/src/features/projects/AGENTS.md +1 -2
- package/src/features/projects/components/project-agreement.tsx +36 -77
- package/src/features/projects/components/project-artifacts.test.tsx +90 -62
- package/src/features/projects/components/project-artifacts.tsx +81 -160
- package/src/features/projects/components/project-materials.test.tsx +80 -0
- package/src/features/projects/components/project-overview.test.tsx +50 -40
- package/src/features/projects/components/project-overview.tsx +5 -4
- package/src/features/projects/components/project-skills.tsx +24 -14
- package/src/features/projects/components/work/project-work-item-drawer.test.tsx +3 -2
- package/src/features/projects/components/work/project-work-items.test.tsx +13 -1
- package/src/features/projects/components/work/project-work-items.tsx +7 -7
- package/src/features/projects/hooks/use-project-materials.test.tsx +65 -0
- package/src/features/projects/hooks/use-project-materials.ts +24 -0
- package/src/features/projects/hooks/use-project-work.test.tsx +57 -1
- package/src/features/projects/hooks/use-project-work.ts +11 -5
- package/src/features/projects/pages/project-home-page.tsx +51 -127
- package/src/features/projects/pages/projects-page.test.tsx +68 -75
- package/src/features/projects/presenters/project-home.presenter.test.ts +1 -64
- package/src/features/projects/presenters/project-home.presenter.ts +17 -54
- package/src/features/projects/utils/project-artifact-view.utils.test.ts +0 -46
- package/src/features/projects/utils/project-artifact-view.utils.ts +0 -47
- package/src/features/settings/pages/keyboard-shortcuts-settings-page.tsx +15 -0
- package/src/platforms/mobile/components/mobile-settings-shell.tsx +2 -1
- package/src/shared/lib/api/__tests__/ncp-session-query-cache.utils.test.ts +109 -1
- package/src/shared/lib/api/ncp-session-query-cache.utils.ts +71 -2
- package/src/shared/lib/i18n/locales/en-US/chat.json +32 -1
- package/src/shared/lib/i18n/locales/en-US/core.json +2 -0
- package/src/shared/lib/i18n/locales/en-US/projects.json +8 -59
- package/src/shared/lib/i18n/locales/zh-CN/chat.json +32 -1
- package/src/shared/lib/i18n/locales/zh-CN/core.json +2 -0
- package/src/shared/lib/i18n/locales/zh-CN/projects.json +8 -59
- package/src/shared/lib/transport/__tests__/browser-realtime-recovery.service.test.ts +42 -0
- package/src/shared/lib/transport/__tests__/local-transport.service.test.ts +85 -0
- package/src/shared/lib/transport/__tests__/remote.transport.test.ts +54 -1
- package/src/shared/lib/transport/browser-realtime-recovery.service.ts +35 -0
- package/src/shared/lib/transport/local-transport.service.ts +32 -0
- package/src/shared/lib/transport/remote-transport.service.ts +30 -0
- package/dist/assets/app-presenter-provider-CLsFiXvV.js +0 -109
- package/dist/assets/doc-browser-w4eGZXLu.js +0 -1
- package/dist/assets/loader-circle-rWr5Yo0E.js +0 -1
- package/dist/assets/login-page-CfMSkOsg.js +0 -1
- package/dist/assets/main-8cVkMfgE.css +0 -1
- package/dist/assets/main-Bys58GxY.js +0 -2
- package/dist/assets/main-i18n-catalog.config-BSq9yiUQ.js +0 -1
- package/dist/assets/mcp-marketplace-page-DX5VE3mU.js +0 -1
- package/dist/assets/panel-app-BUUle0gP.js +0 -1
- package/dist/assets/panel-app-i18n-catalog.config-C2St67SP.js +0 -1
- package/dist/assets/plus-BHnKwuPq.js +0 -1
- package/dist/assets/projects-DV3UuJMS.js +0 -1
- package/dist/assets/remote-Bl005fzu.js +0 -1
- package/dist/assets/runtime-config-page-CmktQcMW.js +0 -1
- package/dist/assets/security-config-Djptuyf2.js +0 -1
- package/dist/assets/skeleton-Eh64l4T2.js +0 -1
- package/dist/assets/x-C0iaOsRW.js +0 -1
- package/src/features/projects/components/project-requests.tsx +0 -57
- package/src/features/projects/components/project-runs.tsx +0 -60
- package/src/features/projects/hooks/use-project-observation.test.tsx +0 -93
- package/src/features/projects/hooks/use-project-observation.ts +0 -115
- package/src/features/projects/utils/project-request-response.utils.test.ts +0 -44
- package/src/features/projects/utils/project-request-response.utils.ts +0 -39
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { systemStatusManager } from '@/features/system-status';
|
|
2
2
|
import type { AppEvent, AppTransport, RequestInput, StreamInput, StreamSession } from './transport.types';
|
|
3
|
+
import { BrowserRealtimeRecoveryService } from './browser-realtime-recovery.service';
|
|
3
4
|
import { requestRawApiResponse } from './request-raw-api-response.utils';
|
|
4
5
|
import { readSseStreamResult } from './sse-stream.utils';
|
|
5
6
|
import { resolveTransportWebSocketUrl } from './transport-websocket-url.utils';
|
|
@@ -53,13 +54,18 @@ class LocalRealtimeGateway {
|
|
|
53
54
|
private socket: WebSocket | null = null;
|
|
54
55
|
private reconnectTimer: number | null = null;
|
|
55
56
|
private manualClose = false;
|
|
57
|
+
private replacingAfterBrowserRecovery = false;
|
|
56
58
|
private subscribers = new Set<EventHandler>();
|
|
59
|
+
private readonly browserRecovery = new BrowserRealtimeRecoveryService(() => {
|
|
60
|
+
this.replaceSocket();
|
|
61
|
+
});
|
|
57
62
|
|
|
58
63
|
constructor(private readonly wsUrl: string) {}
|
|
59
64
|
|
|
60
65
|
subscribe = (handler: EventHandler): () => void => {
|
|
61
66
|
this.subscribers.add(handler);
|
|
62
67
|
if (this.subscribers.size === 1) {
|
|
68
|
+
this.browserRecovery.start();
|
|
63
69
|
this.connect();
|
|
64
70
|
} else if (this.socket?.readyState === WebSocket.OPEN) {
|
|
65
71
|
handler({ type: 'connection.open', payload: {} });
|
|
@@ -68,6 +74,7 @@ class LocalRealtimeGateway {
|
|
|
68
74
|
return () => {
|
|
69
75
|
this.subscribers.delete(handler);
|
|
70
76
|
if (this.subscribers.size === 0) {
|
|
77
|
+
this.browserRecovery.stop();
|
|
71
78
|
this.disconnect();
|
|
72
79
|
}
|
|
73
80
|
};
|
|
@@ -88,6 +95,7 @@ class LocalRealtimeGateway {
|
|
|
88
95
|
this.socket = socket;
|
|
89
96
|
|
|
90
97
|
socket.onopen = () => {
|
|
98
|
+
this.replacingAfterBrowserRecovery = false;
|
|
91
99
|
this.emit({ type: 'connection.open', payload: {} });
|
|
92
100
|
};
|
|
93
101
|
|
|
@@ -105,6 +113,7 @@ class LocalRealtimeGateway {
|
|
|
105
113
|
};
|
|
106
114
|
|
|
107
115
|
socket.onclose = () => {
|
|
116
|
+
this.replacingAfterBrowserRecovery = false;
|
|
108
117
|
this.emit({ type: 'connection.close', payload: {} });
|
|
109
118
|
this.socket = null;
|
|
110
119
|
if (!this.manualClose && this.subscribers.size > 0) {
|
|
@@ -123,8 +132,31 @@ class LocalRealtimeGateway {
|
|
|
123
132
|
}, 3_000);
|
|
124
133
|
};
|
|
125
134
|
|
|
135
|
+
private replaceSocket = (): void => {
|
|
136
|
+
if (this.subscribers.size === 0 || this.replacingAfterBrowserRecovery) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
this.replacingAfterBrowserRecovery = true;
|
|
140
|
+
if (this.reconnectTimer !== null) {
|
|
141
|
+
window.clearTimeout(this.reconnectTimer);
|
|
142
|
+
this.reconnectTimer = null;
|
|
143
|
+
}
|
|
144
|
+
const staleSocket = this.socket;
|
|
145
|
+
this.socket = null;
|
|
146
|
+
if (staleSocket) {
|
|
147
|
+
staleSocket.onopen = null;
|
|
148
|
+
staleSocket.onmessage = null;
|
|
149
|
+
staleSocket.onerror = null;
|
|
150
|
+
staleSocket.onclose = null;
|
|
151
|
+
staleSocket.close();
|
|
152
|
+
this.emit({ type: 'connection.close', payload: {} });
|
|
153
|
+
}
|
|
154
|
+
this.connect();
|
|
155
|
+
};
|
|
156
|
+
|
|
126
157
|
private disconnect = (): void => {
|
|
127
158
|
this.manualClose = true;
|
|
159
|
+
this.replacingAfterBrowserRecovery = false;
|
|
128
160
|
if (this.reconnectTimer !== null) {
|
|
129
161
|
window.clearTimeout(this.reconnectTimer);
|
|
130
162
|
this.reconnectTimer = null;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ApiError } from '@nextclaw/client-sdk';
|
|
2
2
|
import type { AppEvent, AppTransport, RemoteRuntimeInfo, RequestInput, StreamInput, StreamSession } from './transport.types';
|
|
3
|
+
import { BrowserRealtimeRecoveryService } from './browser-realtime-recovery.service';
|
|
3
4
|
import { resolveTransportWebSocketUrl } from './transport-websocket-url.utils';
|
|
4
5
|
|
|
5
6
|
type RemoteTarget = {
|
|
@@ -95,6 +96,9 @@ export class RemoteSessionMultiplexTransport implements AppTransport {
|
|
|
95
96
|
private subscribers = new Set<(event: AppEvent) => void>();
|
|
96
97
|
private pendingRequests = new Map<string, PendingRequest>();
|
|
97
98
|
private pendingStreams = new Map<string, PendingStream>();
|
|
99
|
+
private readonly browserRecovery = new BrowserRealtimeRecoveryService(() => {
|
|
100
|
+
this.replaceSocket();
|
|
101
|
+
});
|
|
98
102
|
|
|
99
103
|
constructor(
|
|
100
104
|
private readonly runtime: RemoteRuntimeInfo,
|
|
@@ -215,6 +219,7 @@ export class RemoteSessionMultiplexTransport implements AppTransport {
|
|
|
215
219
|
|
|
216
220
|
subscribe = (handler: (event: AppEvent) => void): () => void => {
|
|
217
221
|
this.subscribers.add(handler);
|
|
222
|
+
this.browserRecovery.start();
|
|
218
223
|
void this.ensureSocket().catch((error) => {
|
|
219
224
|
handler({
|
|
220
225
|
type: 'connection.error',
|
|
@@ -223,6 +228,9 @@ export class RemoteSessionMultiplexTransport implements AppTransport {
|
|
|
223
228
|
});
|
|
224
229
|
return () => {
|
|
225
230
|
this.subscribers.delete(handler);
|
|
231
|
+
if (this.subscribers.size === 0) {
|
|
232
|
+
this.browserRecovery.stop();
|
|
233
|
+
}
|
|
226
234
|
};
|
|
227
235
|
}
|
|
228
236
|
|
|
@@ -321,6 +329,28 @@ export class RemoteSessionMultiplexTransport implements AppTransport {
|
|
|
321
329
|
}, 3_000);
|
|
322
330
|
}
|
|
323
331
|
|
|
332
|
+
private replaceSocket = (): void => {
|
|
333
|
+
if (this.subscribers.size === 0 || this.connectPromise !== null) {
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
if (this.reconnectTimer !== null) {
|
|
337
|
+
window.clearTimeout(this.reconnectTimer);
|
|
338
|
+
this.reconnectTimer = null;
|
|
339
|
+
}
|
|
340
|
+
const staleSocket = this.socket;
|
|
341
|
+
this.socket = null;
|
|
342
|
+
if (staleSocket) {
|
|
343
|
+
staleSocket.onopen = null;
|
|
344
|
+
staleSocket.onmessage = null;
|
|
345
|
+
staleSocket.onerror = null;
|
|
346
|
+
staleSocket.onclose = null;
|
|
347
|
+
staleSocket.close();
|
|
348
|
+
this.failPendingWork(new Error('Remote transport connection replaced after browser recovery.'));
|
|
349
|
+
this.emit({ type: 'connection.close', payload: {} });
|
|
350
|
+
}
|
|
351
|
+
void this.ensureSocket().catch(() => undefined);
|
|
352
|
+
}
|
|
353
|
+
|
|
324
354
|
private failPendingWork = (error: Error): void => {
|
|
325
355
|
for (const pending of this.pendingRequests.values()) {
|
|
326
356
|
window.clearTimeout(pending.timeoutId);
|