@lobehub/lobehub 2.0.0-next.142 → 2.0.0-next.143
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 +25 -0
- package/apps/desktop/package.json +1 -0
- package/apps/desktop/src/main/core/ui/__tests__/MenuManager.test.ts +320 -0
- package/apps/desktop/src/main/core/ui/__tests__/Tray.test.ts +518 -0
- package/apps/desktop/src/main/core/ui/__tests__/TrayManager.test.ts +360 -0
- package/apps/desktop/src/main/menus/impls/BaseMenuPlatform.test.ts +49 -0
- package/apps/desktop/src/main/menus/impls/linux.test.ts +552 -0
- package/apps/desktop/src/main/menus/impls/macOS.test.ts +464 -0
- package/apps/desktop/src/main/menus/impls/windows.test.ts +429 -0
- package/apps/desktop/src/main/modules/fileSearch/__tests__/macOS.integration.test.ts +2 -2
- package/apps/desktop/src/main/services/__tests__/fileSearchSrv.test.ts +402 -0
- package/apps/desktop/src/main/utils/__tests__/file-system.test.ts +91 -0
- package/apps/desktop/src/main/utils/__tests__/logger.test.ts +229 -0
- package/apps/desktop/src/preload/electronApi.test.ts +142 -0
- package/apps/desktop/src/preload/invoke.test.ts +145 -0
- package/apps/desktop/src/preload/routeInterceptor.test.ts +374 -0
- package/apps/desktop/src/preload/streamer.test.ts +365 -0
- package/apps/desktop/vitest.config.mts +1 -0
- package/changelog/v1.json +9 -0
- package/locales/ar/marketAuth.json +13 -0
- package/locales/bg-BG/marketAuth.json +13 -0
- package/locales/de-DE/marketAuth.json +13 -0
- package/locales/en-US/marketAuth.json +13 -0
- package/locales/es-ES/marketAuth.json +13 -0
- package/locales/fa-IR/marketAuth.json +13 -0
- package/locales/fr-FR/marketAuth.json +13 -0
- package/locales/it-IT/marketAuth.json +13 -0
- package/locales/ja-JP/marketAuth.json +13 -0
- package/locales/ko-KR/marketAuth.json +13 -0
- package/locales/nl-NL/marketAuth.json +13 -0
- package/locales/pl-PL/marketAuth.json +13 -0
- package/locales/pt-BR/marketAuth.json +13 -0
- package/locales/ru-RU/marketAuth.json +13 -0
- package/locales/tr-TR/marketAuth.json +13 -0
- package/locales/vi-VN/marketAuth.json +13 -0
- package/locales/zh-CN/marketAuth.json +13 -0
- package/locales/zh-TW/marketAuth.json +13 -0
- package/package.json +1 -1
- package/packages/database/src/models/user.ts +2 -0
- package/packages/types/src/discover/mcp.ts +2 -1
- package/packages/types/src/tool/plugin.ts +2 -1
- package/src/app/[variants]/(main)/chat/settings/features/SmartAgentActionButton/MarketPublishButton.tsx +0 -2
- package/src/app/[variants]/(main)/discover/(detail)/mcp/features/Sidebar/ActionButton/index.tsx +33 -7
- package/src/features/PluginStore/McpList/List/Action.tsx +20 -1
- package/src/layout/AuthProvider/MarketAuth/MarketAuthConfirmModal.tsx +158 -0
- package/src/layout/AuthProvider/MarketAuth/MarketAuthProvider.tsx +130 -14
- package/src/libs/mcp/types.ts +8 -0
- package/src/locales/default/marketAuth.ts +13 -0
- package/src/server/routers/lambda/market/index.ts +85 -2
- package/src/server/services/discover/index.ts +45 -4
- package/src/services/discover.ts +1 -1
- package/src/services/mcp.ts +18 -3
- package/src/store/tool/slices/mcpStore/action.test.ts +141 -0
- package/src/store/tool/slices/mcpStore/action.ts +153 -11
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
import type { ProxyTRPCRequestParams } from '@lobechat/electron-client-ipc';
|
|
2
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
3
|
+
|
|
4
|
+
// Mock electron module
|
|
5
|
+
const mockIpcRendererOn = vi.fn();
|
|
6
|
+
const mockIpcRendererOnce = vi.fn();
|
|
7
|
+
const mockIpcRendererSend = vi.fn();
|
|
8
|
+
const mockIpcRendererRemoveAllListeners = vi.fn();
|
|
9
|
+
|
|
10
|
+
vi.mock('electron', () => ({
|
|
11
|
+
ipcRenderer: {
|
|
12
|
+
on: mockIpcRendererOn,
|
|
13
|
+
once: mockIpcRendererOnce,
|
|
14
|
+
removeAllListeners: mockIpcRendererRemoveAllListeners,
|
|
15
|
+
send: mockIpcRendererSend,
|
|
16
|
+
},
|
|
17
|
+
}));
|
|
18
|
+
|
|
19
|
+
// Mock uuid
|
|
20
|
+
vi.mock('uuid', () => ({
|
|
21
|
+
v4: vi.fn(() => 'test-request-id-123'),
|
|
22
|
+
}));
|
|
23
|
+
|
|
24
|
+
const { onStreamInvoke } = await import('./streamer');
|
|
25
|
+
|
|
26
|
+
describe('onStreamInvoke', () => {
|
|
27
|
+
beforeEach(() => {
|
|
28
|
+
vi.clearAllMocks();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('should set up stream listeners and send start event', () => {
|
|
32
|
+
const params: ProxyTRPCRequestParams = {
|
|
33
|
+
input: { query: 'test' },
|
|
34
|
+
path: 'test.endpoint',
|
|
35
|
+
type: 'query',
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const callbacks = {
|
|
39
|
+
onData: vi.fn(),
|
|
40
|
+
onEnd: vi.fn(),
|
|
41
|
+
onError: vi.fn(),
|
|
42
|
+
onResponse: vi.fn(),
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
onStreamInvoke(params, callbacks);
|
|
46
|
+
|
|
47
|
+
// Verify listeners are registered
|
|
48
|
+
expect(mockIpcRendererOn).toHaveBeenCalledWith(
|
|
49
|
+
'stream:data:test-request-id-123',
|
|
50
|
+
expect.any(Function),
|
|
51
|
+
);
|
|
52
|
+
expect(mockIpcRendererOnce).toHaveBeenCalledWith(
|
|
53
|
+
'stream:end:test-request-id-123',
|
|
54
|
+
expect.any(Function),
|
|
55
|
+
);
|
|
56
|
+
expect(mockIpcRendererOnce).toHaveBeenCalledWith(
|
|
57
|
+
'stream:error:test-request-id-123',
|
|
58
|
+
expect.any(Function),
|
|
59
|
+
);
|
|
60
|
+
expect(mockIpcRendererOnce).toHaveBeenCalledWith(
|
|
61
|
+
'stream:response:test-request-id-123',
|
|
62
|
+
expect.any(Function),
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
// Verify start event is sent
|
|
66
|
+
expect(mockIpcRendererSend).toHaveBeenCalledWith('stream:start', {
|
|
67
|
+
...params,
|
|
68
|
+
requestId: 'test-request-id-123',
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('should invoke onData callback when data is received', () => {
|
|
73
|
+
const callbacks = {
|
|
74
|
+
onData: vi.fn(),
|
|
75
|
+
onEnd: vi.fn(),
|
|
76
|
+
onError: vi.fn(),
|
|
77
|
+
onResponse: vi.fn(),
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const params: ProxyTRPCRequestParams = {
|
|
81
|
+
input: {},
|
|
82
|
+
path: 'test',
|
|
83
|
+
type: 'query',
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
onStreamInvoke(params, callbacks);
|
|
87
|
+
|
|
88
|
+
// Get the data listener callback
|
|
89
|
+
const dataListener = mockIpcRendererOn.mock.calls.find((call) =>
|
|
90
|
+
call[0].includes('stream:data'),
|
|
91
|
+
)?.[1];
|
|
92
|
+
|
|
93
|
+
// Simulate data event
|
|
94
|
+
const testData = Buffer.from('test data');
|
|
95
|
+
dataListener?.(null, testData);
|
|
96
|
+
|
|
97
|
+
expect(callbacks.onData).toHaveBeenCalledWith(new Uint8Array(testData));
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('should invoke onResponse callback when response is received', () => {
|
|
101
|
+
const callbacks = {
|
|
102
|
+
onData: vi.fn(),
|
|
103
|
+
onEnd: vi.fn(),
|
|
104
|
+
onError: vi.fn(),
|
|
105
|
+
onResponse: vi.fn(),
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const params: ProxyTRPCRequestParams = {
|
|
109
|
+
input: {},
|
|
110
|
+
path: 'test',
|
|
111
|
+
type: 'query',
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
onStreamInvoke(params, callbacks);
|
|
115
|
+
|
|
116
|
+
// Get the response listener callback
|
|
117
|
+
const responseListener = mockIpcRendererOnce.mock.calls.find((call) =>
|
|
118
|
+
call[0].includes('stream:response'),
|
|
119
|
+
)?.[1];
|
|
120
|
+
|
|
121
|
+
// Simulate response event
|
|
122
|
+
const testResponse = {
|
|
123
|
+
headers: { 'content-type': 'application/json' },
|
|
124
|
+
status: 200,
|
|
125
|
+
statusText: 'OK',
|
|
126
|
+
};
|
|
127
|
+
responseListener?.(null, testResponse);
|
|
128
|
+
|
|
129
|
+
expect(callbacks.onResponse).toHaveBeenCalledWith(testResponse);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('should invoke onEnd callback and cleanup when stream ends', () => {
|
|
133
|
+
const callbacks = {
|
|
134
|
+
onData: vi.fn(),
|
|
135
|
+
onEnd: vi.fn(),
|
|
136
|
+
onError: vi.fn(),
|
|
137
|
+
onResponse: vi.fn(),
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const params: ProxyTRPCRequestParams = {
|
|
141
|
+
input: {},
|
|
142
|
+
path: 'test',
|
|
143
|
+
type: 'query',
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
onStreamInvoke(params, callbacks);
|
|
147
|
+
|
|
148
|
+
// Get the end listener callback
|
|
149
|
+
const endListener = mockIpcRendererOnce.mock.calls.find((call) =>
|
|
150
|
+
call[0].includes('stream:end'),
|
|
151
|
+
)?.[1];
|
|
152
|
+
|
|
153
|
+
// Simulate end event
|
|
154
|
+
endListener?.(null);
|
|
155
|
+
|
|
156
|
+
expect(callbacks.onEnd).toHaveBeenCalled();
|
|
157
|
+
|
|
158
|
+
// Verify cleanup
|
|
159
|
+
expect(mockIpcRendererRemoveAllListeners).toHaveBeenCalledWith(
|
|
160
|
+
'stream:data:test-request-id-123',
|
|
161
|
+
);
|
|
162
|
+
expect(mockIpcRendererRemoveAllListeners).toHaveBeenCalledWith(
|
|
163
|
+
'stream:end:test-request-id-123',
|
|
164
|
+
);
|
|
165
|
+
expect(mockIpcRendererRemoveAllListeners).toHaveBeenCalledWith(
|
|
166
|
+
'stream:error:test-request-id-123',
|
|
167
|
+
);
|
|
168
|
+
expect(mockIpcRendererRemoveAllListeners).toHaveBeenCalledWith(
|
|
169
|
+
'stream:response:test-request-id-123',
|
|
170
|
+
);
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
it('should invoke onError callback and cleanup when error occurs', () => {
|
|
174
|
+
const callbacks = {
|
|
175
|
+
onData: vi.fn(),
|
|
176
|
+
onEnd: vi.fn(),
|
|
177
|
+
onError: vi.fn(),
|
|
178
|
+
onResponse: vi.fn(),
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
const params: ProxyTRPCRequestParams = {
|
|
182
|
+
input: {},
|
|
183
|
+
path: 'test',
|
|
184
|
+
type: 'query',
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
onStreamInvoke(params, callbacks);
|
|
188
|
+
|
|
189
|
+
// Get the error listener callback
|
|
190
|
+
const errorListener = mockIpcRendererOnce.mock.calls.find((call) =>
|
|
191
|
+
call[0].includes('stream:error'),
|
|
192
|
+
)?.[1];
|
|
193
|
+
|
|
194
|
+
// Simulate error event
|
|
195
|
+
const testError = new Error('Stream processing failed');
|
|
196
|
+
errorListener?.(null, testError);
|
|
197
|
+
|
|
198
|
+
expect(callbacks.onError).toHaveBeenCalledWith(testError);
|
|
199
|
+
|
|
200
|
+
// Verify cleanup
|
|
201
|
+
expect(mockIpcRendererRemoveAllListeners).toHaveBeenCalledWith(
|
|
202
|
+
'stream:data:test-request-id-123',
|
|
203
|
+
);
|
|
204
|
+
expect(mockIpcRendererRemoveAllListeners).toHaveBeenCalledWith(
|
|
205
|
+
'stream:end:test-request-id-123',
|
|
206
|
+
);
|
|
207
|
+
expect(mockIpcRendererRemoveAllListeners).toHaveBeenCalledWith(
|
|
208
|
+
'stream:error:test-request-id-123',
|
|
209
|
+
);
|
|
210
|
+
expect(mockIpcRendererRemoveAllListeners).toHaveBeenCalledWith(
|
|
211
|
+
'stream:response:test-request-id-123',
|
|
212
|
+
);
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
it('should return cleanup function that removes all listeners', () => {
|
|
216
|
+
const callbacks = {
|
|
217
|
+
onData: vi.fn(),
|
|
218
|
+
onEnd: vi.fn(),
|
|
219
|
+
onError: vi.fn(),
|
|
220
|
+
onResponse: vi.fn(),
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
const params: ProxyTRPCRequestParams = {
|
|
224
|
+
input: {},
|
|
225
|
+
path: 'test',
|
|
226
|
+
type: 'query',
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
const cleanup = onStreamInvoke(params, callbacks);
|
|
230
|
+
|
|
231
|
+
// Call cleanup function
|
|
232
|
+
cleanup();
|
|
233
|
+
|
|
234
|
+
// Verify all listeners are removed
|
|
235
|
+
expect(mockIpcRendererRemoveAllListeners).toHaveBeenCalledWith(
|
|
236
|
+
'stream:data:test-request-id-123',
|
|
237
|
+
);
|
|
238
|
+
expect(mockIpcRendererRemoveAllListeners).toHaveBeenCalledWith(
|
|
239
|
+
'stream:end:test-request-id-123',
|
|
240
|
+
);
|
|
241
|
+
expect(mockIpcRendererRemoveAllListeners).toHaveBeenCalledWith(
|
|
242
|
+
'stream:error:test-request-id-123',
|
|
243
|
+
);
|
|
244
|
+
expect(mockIpcRendererRemoveAllListeners).toHaveBeenCalledWith(
|
|
245
|
+
'stream:response:test-request-id-123',
|
|
246
|
+
);
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
it('should handle multiple data chunks', () => {
|
|
250
|
+
const callbacks = {
|
|
251
|
+
onData: vi.fn(),
|
|
252
|
+
onEnd: vi.fn(),
|
|
253
|
+
onError: vi.fn(),
|
|
254
|
+
onResponse: vi.fn(),
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
const params: ProxyTRPCRequestParams = {
|
|
258
|
+
input: {},
|
|
259
|
+
path: 'test',
|
|
260
|
+
type: 'query',
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
onStreamInvoke(params, callbacks);
|
|
264
|
+
|
|
265
|
+
const dataListener = mockIpcRendererOn.mock.calls.find((call) =>
|
|
266
|
+
call[0].includes('stream:data'),
|
|
267
|
+
)?.[1];
|
|
268
|
+
|
|
269
|
+
// Simulate multiple data chunks
|
|
270
|
+
const chunk1 = Buffer.from('chunk1');
|
|
271
|
+
const chunk2 = Buffer.from('chunk2');
|
|
272
|
+
const chunk3 = Buffer.from('chunk3');
|
|
273
|
+
|
|
274
|
+
dataListener?.(null, chunk1);
|
|
275
|
+
dataListener?.(null, chunk2);
|
|
276
|
+
dataListener?.(null, chunk3);
|
|
277
|
+
|
|
278
|
+
expect(callbacks.onData).toHaveBeenCalledTimes(3);
|
|
279
|
+
expect(callbacks.onData).toHaveBeenNthCalledWith(1, new Uint8Array(chunk1));
|
|
280
|
+
expect(callbacks.onData).toHaveBeenNthCalledWith(2, new Uint8Array(chunk2));
|
|
281
|
+
expect(callbacks.onData).toHaveBeenNthCalledWith(3, new Uint8Array(chunk3));
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
it('should handle complex request parameters', () => {
|
|
285
|
+
const callbacks = {
|
|
286
|
+
onData: vi.fn(),
|
|
287
|
+
onEnd: vi.fn(),
|
|
288
|
+
onError: vi.fn(),
|
|
289
|
+
onResponse: vi.fn(),
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
const params: ProxyTRPCRequestParams = {
|
|
293
|
+
input: {
|
|
294
|
+
filters: { active: true },
|
|
295
|
+
query: 'complex query',
|
|
296
|
+
sort: { field: 'date', order: 'desc' },
|
|
297
|
+
},
|
|
298
|
+
path: 'complex.nested.endpoint',
|
|
299
|
+
type: 'mutation',
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
onStreamInvoke(params, callbacks);
|
|
303
|
+
|
|
304
|
+
expect(mockIpcRendererSend).toHaveBeenCalledWith('stream:start', {
|
|
305
|
+
...params,
|
|
306
|
+
requestId: 'test-request-id-123',
|
|
307
|
+
});
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
it('should not invoke callbacks after cleanup', () => {
|
|
311
|
+
const callbacks = {
|
|
312
|
+
onData: vi.fn(),
|
|
313
|
+
onEnd: vi.fn(),
|
|
314
|
+
onError: vi.fn(),
|
|
315
|
+
onResponse: vi.fn(),
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
const params: ProxyTRPCRequestParams = {
|
|
319
|
+
input: {},
|
|
320
|
+
path: 'test',
|
|
321
|
+
type: 'query',
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
const cleanup = onStreamInvoke(params, callbacks);
|
|
325
|
+
|
|
326
|
+
// Cleanup immediately
|
|
327
|
+
cleanup();
|
|
328
|
+
|
|
329
|
+
// Try to trigger callbacks after cleanup (this simulates late events)
|
|
330
|
+
const dataListener = mockIpcRendererOn.mock.calls.find((call) =>
|
|
331
|
+
call[0].includes('stream:data'),
|
|
332
|
+
)?.[1];
|
|
333
|
+
|
|
334
|
+
// Since listeners are removed, this shouldn't do anything
|
|
335
|
+
// The actual behavior depends on electron's implementation
|
|
336
|
+
// But we can verify cleanup was called
|
|
337
|
+
expect(mockIpcRendererRemoveAllListeners).toHaveBeenCalledTimes(4);
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
it('should handle empty buffer data', () => {
|
|
341
|
+
const callbacks = {
|
|
342
|
+
onData: vi.fn(),
|
|
343
|
+
onEnd: vi.fn(),
|
|
344
|
+
onError: vi.fn(),
|
|
345
|
+
onResponse: vi.fn(),
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
const params: ProxyTRPCRequestParams = {
|
|
349
|
+
input: {},
|
|
350
|
+
path: 'test',
|
|
351
|
+
type: 'query',
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
onStreamInvoke(params, callbacks);
|
|
355
|
+
|
|
356
|
+
const dataListener = mockIpcRendererOn.mock.calls.find((call) =>
|
|
357
|
+
call[0].includes('stream:data'),
|
|
358
|
+
)?.[1];
|
|
359
|
+
|
|
360
|
+
const emptyBuffer = Buffer.from('');
|
|
361
|
+
dataListener?.(null, emptyBuffer);
|
|
362
|
+
|
|
363
|
+
expect(callbacks.onData).toHaveBeenCalledWith(new Uint8Array(emptyBuffer));
|
|
364
|
+
});
|
|
365
|
+
});
|
package/changelog/v1.json
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
{
|
|
2
|
+
"authorize": {
|
|
3
|
+
"cancel": "إلغاء",
|
|
4
|
+
"confirm": "تأكيد التفويض",
|
|
5
|
+
"description": {
|
|
6
|
+
"and": "و",
|
|
7
|
+
"prefix": "بالنقر على تأكيد التفويض، فإنك توافق على",
|
|
8
|
+
"privacy": "سياسة الخصوصية",
|
|
9
|
+
"terms": "شروط الخدمة"
|
|
10
|
+
},
|
|
11
|
+
"title": "تأكيد التفويض"
|
|
12
|
+
},
|
|
2
13
|
"callback": {
|
|
3
14
|
"buttons": {
|
|
4
15
|
"close": "إغلاق النافذة"
|
|
@@ -33,8 +44,10 @@
|
|
|
33
44
|
"stateMissing": "لم يتم العثور على حالة التفويض، يرجى المحاولة مرة أخرى."
|
|
34
45
|
},
|
|
35
46
|
"messages": {
|
|
47
|
+
"authorized": "تم تفويض خدمة LobeHub بنجاح",
|
|
36
48
|
"loading": "جارٍ بدء عملية التفويض...",
|
|
37
49
|
"success": {
|
|
50
|
+
"cloudMcpInstall": "تم التفويض بنجاح! يمكنك الآن تثبيت إضافة Cloud MCP.",
|
|
38
51
|
"submit": "تم التفويض بنجاح! يمكنك الآن نشر المساعد.",
|
|
39
52
|
"upload": "تم التفويض بنجاح! يمكنك الآن نشر إصدار جديد."
|
|
40
53
|
}
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
{
|
|
2
|
+
"authorize": {
|
|
3
|
+
"cancel": "Отказ",
|
|
4
|
+
"confirm": "Разреши използването",
|
|
5
|
+
"description": {
|
|
6
|
+
"and": "и",
|
|
7
|
+
"prefix": "С натискане на „Разреши използването“ се съгласявате с",
|
|
8
|
+
"privacy": "Политиката за поверителност",
|
|
9
|
+
"terms": "Условията за ползване"
|
|
10
|
+
},
|
|
11
|
+
"title": "Потвърждаване на оторизацията"
|
|
12
|
+
},
|
|
2
13
|
"callback": {
|
|
3
14
|
"buttons": {
|
|
4
15
|
"close": "Затвори прозореца"
|
|
@@ -33,8 +44,10 @@
|
|
|
33
44
|
"stateMissing": "Състоянието на упълномощаване не бе намерено, моля опитайте отново."
|
|
34
45
|
},
|
|
35
46
|
"messages": {
|
|
47
|
+
"authorized": "Успешно упълномощаване на услугата LobeHub",
|
|
36
48
|
"loading": "Стартиране на процеса по упълномощаване...",
|
|
37
49
|
"success": {
|
|
50
|
+
"cloudMcpInstall": "Успешно разрешение! Вече можете да инсталирате приставката Cloud MCP.",
|
|
38
51
|
"submit": "Упълномощаването е успешно! Вече можете да публикувате помощник.",
|
|
39
52
|
"upload": "Упълномощаването е успешно! Вече можете да публикувате нова версия."
|
|
40
53
|
}
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
{
|
|
2
|
+
"authorize": {
|
|
3
|
+
"cancel": "Abbrechen",
|
|
4
|
+
"confirm": "Autorisieren",
|
|
5
|
+
"description": {
|
|
6
|
+
"and": "und",
|
|
7
|
+
"prefix": "Mit dem Klick auf „Autorisieren“ stimmen Sie den",
|
|
8
|
+
"privacy": "Datenschutzbestimmungen",
|
|
9
|
+
"terms": "Nutzungsbedingungen"
|
|
10
|
+
},
|
|
11
|
+
"title": "Autorisierung bestätigen"
|
|
12
|
+
},
|
|
2
13
|
"callback": {
|
|
3
14
|
"buttons": {
|
|
4
15
|
"close": "Fenster schließen"
|
|
@@ -33,8 +44,10 @@
|
|
|
33
44
|
"stateMissing": "Autorisierungsstatus nicht gefunden, bitte erneut versuchen."
|
|
34
45
|
},
|
|
35
46
|
"messages": {
|
|
47
|
+
"authorized": "LobeHub-Dienst erfolgreich autorisiert",
|
|
36
48
|
"loading": "Autorisierungsvorgang wird gestartet...",
|
|
37
49
|
"success": {
|
|
50
|
+
"cloudMcpInstall": "Autorisierung erfolgreich! Sie können jetzt das Cloud MCP-Plugin installieren.",
|
|
38
51
|
"submit": "Autorisierung erfolgreich! Du kannst jetzt einen Assistenten veröffentlichen.",
|
|
39
52
|
"upload": "Autorisierung erfolgreich! Du kannst jetzt eine neue Version veröffentlichen."
|
|
40
53
|
}
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
{
|
|
2
|
+
"authorize": {
|
|
3
|
+
"cancel": "Cancel",
|
|
4
|
+
"confirm": "Authorize",
|
|
5
|
+
"description": {
|
|
6
|
+
"and": "and",
|
|
7
|
+
"prefix": "By clicking Authorize, you agree to",
|
|
8
|
+
"privacy": "Privacy Policy",
|
|
9
|
+
"terms": "Terms of Service"
|
|
10
|
+
},
|
|
11
|
+
"title": "Confirm Authorization"
|
|
12
|
+
},
|
|
2
13
|
"callback": {
|
|
3
14
|
"buttons": {
|
|
4
15
|
"close": "Close Window"
|
|
@@ -33,8 +44,10 @@
|
|
|
33
44
|
"stateMissing": "Authorization state not found. Please try again."
|
|
34
45
|
},
|
|
35
46
|
"messages": {
|
|
47
|
+
"authorized": "LobeHub service authorized successfully",
|
|
36
48
|
"loading": "Starting authorization process...",
|
|
37
49
|
"success": {
|
|
50
|
+
"cloudMcpInstall": "Authorization successful! You can now install the Cloud MCP plugin.",
|
|
38
51
|
"submit": "Authorization successful! You can now publish your assistant.",
|
|
39
52
|
"upload": "Authorization successful! You can now publish a new version."
|
|
40
53
|
}
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
{
|
|
2
|
+
"authorize": {
|
|
3
|
+
"cancel": "Cancelar",
|
|
4
|
+
"confirm": "Autorizar uso",
|
|
5
|
+
"description": {
|
|
6
|
+
"and": "y",
|
|
7
|
+
"prefix": "Al hacer clic en autorizar uso, se considera que aceptas",
|
|
8
|
+
"privacy": "la Política de Privacidad",
|
|
9
|
+
"terms": "los Términos de Servicio"
|
|
10
|
+
},
|
|
11
|
+
"title": "Confirmar autorización"
|
|
12
|
+
},
|
|
2
13
|
"callback": {
|
|
3
14
|
"buttons": {
|
|
4
15
|
"close": "Cerrar ventana"
|
|
@@ -33,8 +44,10 @@
|
|
|
33
44
|
"stateMissing": "No se encontró el estado de autenticación, por favor inténtalo de nuevo."
|
|
34
45
|
},
|
|
35
46
|
"messages": {
|
|
47
|
+
"authorized": "Autorización del servicio LobeHub realizada con éxito",
|
|
36
48
|
"loading": "Iniciando el proceso de autenticación...",
|
|
37
49
|
"success": {
|
|
50
|
+
"cloudMcpInstall": "¡Autorización exitosa! Ahora puedes instalar el complemento Cloud MCP.",
|
|
38
51
|
"submit": "¡Autenticación exitosa! Ahora puedes publicar asistentes.",
|
|
39
52
|
"upload": "¡Autenticación exitosa! Ahora puedes publicar una nueva versión."
|
|
40
53
|
}
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
{
|
|
2
|
+
"authorize": {
|
|
3
|
+
"cancel": "لغو",
|
|
4
|
+
"confirm": "تأیید مجوز استفاده",
|
|
5
|
+
"description": {
|
|
6
|
+
"and": "و",
|
|
7
|
+
"prefix": "با کلیک بر روی تأیید مجوز استفاده، شما با",
|
|
8
|
+
"privacy": "سیاست حفظ حریم خصوصی",
|
|
9
|
+
"terms": "شرایط خدمات"
|
|
10
|
+
},
|
|
11
|
+
"title": "تأیید مجوز"
|
|
12
|
+
},
|
|
2
13
|
"callback": {
|
|
3
14
|
"buttons": {
|
|
4
15
|
"close": "بستن پنجره"
|
|
@@ -33,8 +44,10 @@
|
|
|
33
44
|
"stateMissing": "وضعیت احراز هویت یافت نشد، لطفاً دوباره تلاش کنید."
|
|
34
45
|
},
|
|
35
46
|
"messages": {
|
|
47
|
+
"authorized": "دسترسی به سرویس LobeHub با موفقیت تأیید شد",
|
|
36
48
|
"loading": "در حال آغاز فرآیند احراز هویت...",
|
|
37
49
|
"success": {
|
|
50
|
+
"cloudMcpInstall": "مجوز با موفقیت صادر شد! اکنون میتوانید افزونه Cloud MCP را نصب کنید.",
|
|
38
51
|
"submit": "احراز هویت با موفقیت انجام شد! اکنون میتوانید دستیار را منتشر کنید.",
|
|
39
52
|
"upload": "احراز هویت با موفقیت انجام شد! اکنون میتوانید نسخه جدیدی منتشر کنید."
|
|
40
53
|
}
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
{
|
|
2
|
+
"authorize": {
|
|
3
|
+
"cancel": "Annuler",
|
|
4
|
+
"confirm": "Autoriser l'utilisation",
|
|
5
|
+
"description": {
|
|
6
|
+
"and": "et",
|
|
7
|
+
"prefix": "En cliquant sur « Autoriser l'utilisation », vous acceptez",
|
|
8
|
+
"privacy": "la Politique de confidentialité",
|
|
9
|
+
"terms": "les Conditions d'utilisation"
|
|
10
|
+
},
|
|
11
|
+
"title": "Confirmer l'autorisation"
|
|
12
|
+
},
|
|
2
13
|
"callback": {
|
|
3
14
|
"buttons": {
|
|
4
15
|
"close": "Fermer la fenêtre"
|
|
@@ -33,8 +44,10 @@
|
|
|
33
44
|
"stateMissing": "État d'autorisation introuvable, veuillez réessayer."
|
|
34
45
|
},
|
|
35
46
|
"messages": {
|
|
47
|
+
"authorized": "Autorisation du service LobeHub réussie",
|
|
36
48
|
"loading": "Lancement du processus d'autorisation...",
|
|
37
49
|
"success": {
|
|
50
|
+
"cloudMcpInstall": "Autorisation réussie ! Vous pouvez maintenant installer le plugin Cloud MCP.",
|
|
38
51
|
"submit": "Autorisation réussie ! Vous pouvez maintenant publier un assistant.",
|
|
39
52
|
"upload": "Autorisation réussie ! Vous pouvez maintenant publier une nouvelle version."
|
|
40
53
|
}
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
{
|
|
2
|
+
"authorize": {
|
|
3
|
+
"cancel": "Annulla",
|
|
4
|
+
"confirm": "Autorizza l'utilizzo",
|
|
5
|
+
"description": {
|
|
6
|
+
"and": "e",
|
|
7
|
+
"prefix": "Facendo clic su 'Autorizza l'utilizzo' si accetta",
|
|
8
|
+
"privacy": "l'Informativa sulla privacy",
|
|
9
|
+
"terms": "i Termini di servizio"
|
|
10
|
+
},
|
|
11
|
+
"title": "Conferma autorizzazione"
|
|
12
|
+
},
|
|
2
13
|
"callback": {
|
|
3
14
|
"buttons": {
|
|
4
15
|
"close": "Chiudi finestra"
|
|
@@ -33,8 +44,10 @@
|
|
|
33
44
|
"stateMissing": "Stato di autorizzazione non trovato, riprova."
|
|
34
45
|
},
|
|
35
46
|
"messages": {
|
|
47
|
+
"authorized": "Autorizzazione al servizio LobeHub avvenuta con successo",
|
|
36
48
|
"loading": "Avvio del processo di autorizzazione in corso...",
|
|
37
49
|
"success": {
|
|
50
|
+
"cloudMcpInstall": "Autorizzazione avvenuta con successo! Ora puoi installare il plugin Cloud MCP.",
|
|
38
51
|
"submit": "Autorizzazione riuscita! Ora puoi pubblicare l'assistente.",
|
|
39
52
|
"upload": "Autorizzazione riuscita! Ora puoi pubblicare una nuova versione."
|
|
40
53
|
}
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
{
|
|
2
|
+
"authorize": {
|
|
3
|
+
"cancel": "キャンセル",
|
|
4
|
+
"confirm": "使用を許可する",
|
|
5
|
+
"description": {
|
|
6
|
+
"and": "および",
|
|
7
|
+
"prefix": "「使用を許可する」をクリックすると、以下に同意したものとみなされます:",
|
|
8
|
+
"privacy": "プライバシーポリシー",
|
|
9
|
+
"terms": "利用規約"
|
|
10
|
+
},
|
|
11
|
+
"title": "認証の確認"
|
|
12
|
+
},
|
|
2
13
|
"callback": {
|
|
3
14
|
"buttons": {
|
|
4
15
|
"close": "ウィンドウを閉じる"
|
|
@@ -33,8 +44,10 @@
|
|
|
33
44
|
"stateMissing": "認証状態が見つかりません。もう一度お試しください。"
|
|
34
45
|
},
|
|
35
46
|
"messages": {
|
|
47
|
+
"authorized": "LobeHub サービスの認証に成功しました",
|
|
36
48
|
"loading": "認証プロセスを開始しています...",
|
|
37
49
|
"success": {
|
|
50
|
+
"cloudMcpInstall": "許可が成功しました!これで Cloud MCP プラグインをインストールできます。",
|
|
38
51
|
"submit": "認証に成功しました!アシスタントを公開できます。",
|
|
39
52
|
"upload": "認証に成功しました!新しいバージョンを公開できます。"
|
|
40
53
|
}
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
{
|
|
2
|
+
"authorize": {
|
|
3
|
+
"cancel": "취소",
|
|
4
|
+
"confirm": "사용 권한 부여",
|
|
5
|
+
"description": {
|
|
6
|
+
"and": "및",
|
|
7
|
+
"prefix": "사용 권한 부여를 클릭하면 다음에 동의한 것으로 간주됩니다",
|
|
8
|
+
"privacy": "개인정보 처리방침",
|
|
9
|
+
"terms": "서비스 이용약관"
|
|
10
|
+
},
|
|
11
|
+
"title": "권한 확인"
|
|
12
|
+
},
|
|
2
13
|
"callback": {
|
|
3
14
|
"buttons": {
|
|
4
15
|
"close": "창 닫기"
|
|
@@ -33,8 +44,10 @@
|
|
|
33
44
|
"stateMissing": "인증 상태를 찾을 수 없습니다. 다시 시도해 주세요."
|
|
34
45
|
},
|
|
35
46
|
"messages": {
|
|
47
|
+
"authorized": "LobeHub 서비스가 성공적으로 인증되었습니다",
|
|
36
48
|
"loading": "인증 절차를 시작하는 중입니다...",
|
|
37
49
|
"success": {
|
|
50
|
+
"cloudMcpInstall": "권한 부여 완료! 이제 Cloud MCP 플러그인을 설치할 수 있습니다.",
|
|
38
51
|
"submit": "인증 성공! 이제 어시스턴트를 게시할 수 있습니다.",
|
|
39
52
|
"upload": "인증 성공! 이제 새 버전을 게시할 수 있습니다."
|
|
40
53
|
}
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
{
|
|
2
|
+
"authorize": {
|
|
3
|
+
"cancel": "Annuleren",
|
|
4
|
+
"confirm": "Toestemming geven",
|
|
5
|
+
"description": {
|
|
6
|
+
"and": "en",
|
|
7
|
+
"prefix": "Door op 'Toestemming geven' te klikken, ga je akkoord met onze",
|
|
8
|
+
"privacy": "Privacybeleid",
|
|
9
|
+
"terms": "Servicevoorwaarden"
|
|
10
|
+
},
|
|
11
|
+
"title": "Autorisatie bevestigen"
|
|
12
|
+
},
|
|
2
13
|
"callback": {
|
|
3
14
|
"buttons": {
|
|
4
15
|
"close": "Venster sluiten"
|
|
@@ -33,8 +44,10 @@
|
|
|
33
44
|
"stateMissing": "Autorisatiestatus niet gevonden, probeer het opnieuw."
|
|
34
45
|
},
|
|
35
46
|
"messages": {
|
|
47
|
+
"authorized": "LobeHub-service succesvol geautoriseerd",
|
|
36
48
|
"loading": "Autorisatieproces wordt gestart...",
|
|
37
49
|
"success": {
|
|
50
|
+
"cloudMcpInstall": "Toestemming succesvol! Je kunt nu de Cloud MCP-plugin installeren.",
|
|
38
51
|
"submit": "Autorisatie geslaagd! Je kunt nu een assistent publiceren.",
|
|
39
52
|
"upload": "Autorisatie geslaagd! Je kunt nu een nieuwe versie publiceren."
|
|
40
53
|
}
|