dsh-edge 0.15.1 → 0.16.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/README.i18n.yaml +2 -2
- package/README.md +1 -1
- package/README.zh.md +1 -1
- package/THIRD_PARTY_NOTICES.md +1862 -60
- package/dist/index.html +1 -1
- package/dist/plugins/dsh-edge-client-ui/client.js +916 -10
- package/package.json +12 -7
- package/worker/direct/index.js +1252 -1221
- package/worker/isolated/index.js +700 -669
|
@@ -274,23 +274,43 @@ window.__ModuleLoader__.load({
|
|
|
274
274
|
return health.ok === true && health.service === "dsh-edge" && health.status === "ready" && (health.shell === "just-bash-direct" || health.shell === "just-bash-isolated") && health.storage === "durable-object-sqlite-vfs" && typeof health.deploymentId === "string" && typeof health.version === "string" && typeof health.upstreamVersion === "string";
|
|
275
275
|
}
|
|
276
276
|
/** Lazy, fail-soft controller for the Edge deployment settings page. */
|
|
277
|
-
var EdgeSettingsController = class {
|
|
277
|
+
var EdgeSettingsController = class EdgeSettingsController {
|
|
278
278
|
io;
|
|
279
279
|
/** Observable settings state consumed by the client runtime. */
|
|
280
280
|
store = (0, _deepseek_ai_dsh_client_store.createSnapshotStore)({
|
|
281
281
|
status: "idle",
|
|
282
282
|
copied: false,
|
|
283
|
-
signingOut: false
|
|
283
|
+
signingOut: false,
|
|
284
|
+
approvalMode: "never",
|
|
285
|
+
approvalSaving: false,
|
|
286
|
+
approvalSaved: false,
|
|
287
|
+
mcpServers: [],
|
|
288
|
+
mcpLoaded: false,
|
|
289
|
+
mcpSaving: false
|
|
284
290
|
});
|
|
285
291
|
loadGeneration = 0;
|
|
292
|
+
approvalGeneration = 0;
|
|
293
|
+
mcpGeneration = 0;
|
|
294
|
+
oauthMessageHandler;
|
|
286
295
|
constructor(io) {
|
|
287
296
|
this.io = io;
|
|
297
|
+
this.oauthMessageHandler = (e) => {
|
|
298
|
+
if (e.data?.type === "mcp-oauth-complete") this.refreshMcpServers();
|
|
299
|
+
};
|
|
300
|
+
globalThis.addEventListener?.("message", this.oauthMessageHandler);
|
|
301
|
+
}
|
|
302
|
+
dispose() {
|
|
303
|
+
if (this.oauthMessageHandler !== void 0) {
|
|
304
|
+
globalThis.removeEventListener?.("message", this.oauthMessageHandler);
|
|
305
|
+
this.oauthMessageHandler = void 0;
|
|
306
|
+
}
|
|
288
307
|
}
|
|
289
308
|
/** Load the current deployment projection without affecting owner-session state. */
|
|
290
309
|
async load() {
|
|
291
310
|
const generation = ++this.loadGeneration;
|
|
292
311
|
this.store.update((state) => {
|
|
293
312
|
state.status = "loading";
|
|
313
|
+
state.mcpLoaded = false;
|
|
294
314
|
delete state.error;
|
|
295
315
|
});
|
|
296
316
|
try {
|
|
@@ -308,6 +328,36 @@ window.__ModuleLoader__.load({
|
|
|
308
328
|
delete state.latestVersion;
|
|
309
329
|
delete state.error;
|
|
310
330
|
});
|
|
331
|
+
const approvalGen = ++this.approvalGeneration;
|
|
332
|
+
try {
|
|
333
|
+
const approvalResponse = await this.io.fetch("/api/approval-mode", { credentials: "same-origin" });
|
|
334
|
+
if (approvalGen === this.approvalGeneration) {
|
|
335
|
+
if (approvalResponse.ok) {
|
|
336
|
+
const data = await approvalResponse.json();
|
|
337
|
+
if (approvalGen === this.approvalGeneration && (data.mode === "ask" || data.mode === "never")) this.store.update((state) => {
|
|
338
|
+
state.approvalMode = data.mode;
|
|
339
|
+
delete state.approvalError;
|
|
340
|
+
});
|
|
341
|
+
} else this.store.update((state) => {
|
|
342
|
+
state.approvalError = `HTTP ${String(approvalResponse.status)}`;
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
} catch {
|
|
346
|
+
if (approvalGen === this.approvalGeneration) this.store.update((state) => {
|
|
347
|
+
state.approvalError = "Could not load approval setting.";
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
const mcpGen = ++this.mcpGeneration;
|
|
351
|
+
try {
|
|
352
|
+
const mcpResponse = await this.io.fetch("/api/mcp-servers", { credentials: "same-origin" });
|
|
353
|
+
if (mcpGen === this.mcpGeneration && mcpResponse.ok) {
|
|
354
|
+
const data = await mcpResponse.json();
|
|
355
|
+
if (mcpGen === this.mcpGeneration && Array.isArray(data.servers)) this.store.update((state) => {
|
|
356
|
+
state.mcpServers = data.servers;
|
|
357
|
+
state.mcpLoaded = true;
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
} catch {}
|
|
311
361
|
let latestVersion;
|
|
312
362
|
try {
|
|
313
363
|
const releaseResponse = await this.io.fetch(`https://registry.npmjs.org/dsh-edge/${channel}`, { signal: AbortSignal.timeout(5e3) });
|
|
@@ -330,7 +380,234 @@ window.__ModuleLoader__.load({
|
|
|
330
380
|
});
|
|
331
381
|
}
|
|
332
382
|
}
|
|
333
|
-
|
|
383
|
+
async setApprovalMode(mode) {
|
|
384
|
+
this.approvalGeneration++;
|
|
385
|
+
this.store.update((state) => {
|
|
386
|
+
state.approvalSaving = true;
|
|
387
|
+
state.approvalSaved = false;
|
|
388
|
+
delete state.approvalError;
|
|
389
|
+
});
|
|
390
|
+
try {
|
|
391
|
+
const response = await this.io.fetch("/api/approval-mode", {
|
|
392
|
+
method: "PUT",
|
|
393
|
+
credentials: "same-origin",
|
|
394
|
+
headers: { "content-type": "application/json" },
|
|
395
|
+
body: JSON.stringify({ mode })
|
|
396
|
+
});
|
|
397
|
+
if (!response.ok) throw new Error(`HTTP ${String(response.status)}`);
|
|
398
|
+
this.store.update((state) => {
|
|
399
|
+
state.approvalMode = mode;
|
|
400
|
+
state.approvalSaving = false;
|
|
401
|
+
state.approvalSaved = true;
|
|
402
|
+
});
|
|
403
|
+
} catch (error) {
|
|
404
|
+
this.store.update((state) => {
|
|
405
|
+
state.approvalSaving = false;
|
|
406
|
+
state.approvalError = messageOf(error);
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
async refreshMcpServers() {
|
|
411
|
+
const mcpGen = ++this.mcpGeneration;
|
|
412
|
+
try {
|
|
413
|
+
const response = await this.io.fetch("/api/mcp-servers", { credentials: "same-origin" });
|
|
414
|
+
if (mcpGen === this.mcpGeneration && response.ok) {
|
|
415
|
+
const data = await response.json();
|
|
416
|
+
if (mcpGen === this.mcpGeneration && Array.isArray(data.servers)) this.store.update((state) => {
|
|
417
|
+
state.mcpServers = data.servers;
|
|
418
|
+
state.mcpLoaded = true;
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
} catch {}
|
|
422
|
+
}
|
|
423
|
+
static stripServerManagedFields(servers) {
|
|
424
|
+
return servers.map(({ serverName, url, auth, toolPolicy, toolCallTimeoutMs }) => ({
|
|
425
|
+
serverName,
|
|
426
|
+
url,
|
|
427
|
+
...auth !== void 0 ? { auth } : {},
|
|
428
|
+
...toolPolicy !== void 0 ? { toolPolicy } : {},
|
|
429
|
+
...toolCallTimeoutMs !== void 0 ? { toolCallTimeoutMs } : {}
|
|
430
|
+
}));
|
|
431
|
+
}
|
|
432
|
+
async saveMcpServers(servers) {
|
|
433
|
+
this.mcpGeneration++;
|
|
434
|
+
this.store.update((state) => {
|
|
435
|
+
state.mcpSaving = true;
|
|
436
|
+
delete state.mcpError;
|
|
437
|
+
});
|
|
438
|
+
try {
|
|
439
|
+
const response = await this.io.fetch("/api/mcp-servers", {
|
|
440
|
+
method: "PUT",
|
|
441
|
+
credentials: "same-origin",
|
|
442
|
+
headers: { "content-type": "application/json" },
|
|
443
|
+
body: JSON.stringify({ servers: EdgeSettingsController.stripServerManagedFields(servers) })
|
|
444
|
+
});
|
|
445
|
+
if (!response.ok) {
|
|
446
|
+
const data = await response.json().catch(() => ({}));
|
|
447
|
+
throw new Error(data.error ?? `HTTP ${String(response.status)}`);
|
|
448
|
+
}
|
|
449
|
+
const saved = (await response.json()).servers ?? servers;
|
|
450
|
+
this.store.update((state) => {
|
|
451
|
+
state.mcpServers = saved;
|
|
452
|
+
});
|
|
453
|
+
const probeErrors = [];
|
|
454
|
+
for (const s of saved) {
|
|
455
|
+
if (s.auth?.type === "oauth") continue;
|
|
456
|
+
try {
|
|
457
|
+
const probeRes = await this.io.fetch(`/api/mcp-servers/${encodeURIComponent(s.serverName)}/probe`, {
|
|
458
|
+
method: "POST",
|
|
459
|
+
credentials: "same-origin"
|
|
460
|
+
});
|
|
461
|
+
if (!probeRes.ok) {
|
|
462
|
+
const data = await probeRes.json().catch(() => ({}));
|
|
463
|
+
probeErrors.push(`${s.serverName}: ${data.error ?? "probe failed"}`);
|
|
464
|
+
}
|
|
465
|
+
} catch {
|
|
466
|
+
probeErrors.push(`${s.serverName}: network error`);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
await this.refreshMcpServers();
|
|
470
|
+
this.store.update((state) => {
|
|
471
|
+
state.mcpSaving = false;
|
|
472
|
+
});
|
|
473
|
+
return true;
|
|
474
|
+
} catch (error) {
|
|
475
|
+
this.store.update((state) => {
|
|
476
|
+
state.mcpSaving = false;
|
|
477
|
+
state.mcpError = messageOf(error);
|
|
478
|
+
});
|
|
479
|
+
return false;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
async setMcpToolPolicy(serverName, mode) {
|
|
483
|
+
const updated = this.store.getSnapshot().mcpServers.map((s) => s.serverName === serverName ? {
|
|
484
|
+
...s,
|
|
485
|
+
toolPolicy: { mode }
|
|
486
|
+
} : s);
|
|
487
|
+
try {
|
|
488
|
+
const response = await this.io.fetch("/api/mcp-servers", {
|
|
489
|
+
method: "PUT",
|
|
490
|
+
credentials: "same-origin",
|
|
491
|
+
headers: { "content-type": "application/json" },
|
|
492
|
+
body: JSON.stringify({ servers: EdgeSettingsController.stripServerManagedFields(updated) })
|
|
493
|
+
});
|
|
494
|
+
if (!response.ok) {
|
|
495
|
+
const data = await response.json().catch(() => ({}));
|
|
496
|
+
this.store.update((state) => {
|
|
497
|
+
state.mcpError = data.error ?? "Policy update failed";
|
|
498
|
+
});
|
|
499
|
+
return false;
|
|
500
|
+
}
|
|
501
|
+
const result = await response.json();
|
|
502
|
+
if (Array.isArray(result.servers)) this.store.update((state) => {
|
|
503
|
+
state.mcpServers = result.servers;
|
|
504
|
+
delete state.mcpError;
|
|
505
|
+
});
|
|
506
|
+
return true;
|
|
507
|
+
} catch {
|
|
508
|
+
return false;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
async probeMcpServer(serverName) {
|
|
512
|
+
try {
|
|
513
|
+
if (!(await this.io.fetch(`/api/mcp-servers/${encodeURIComponent(serverName)}/probe`, {
|
|
514
|
+
method: "POST",
|
|
515
|
+
credentials: "same-origin"
|
|
516
|
+
})).ok) {
|
|
517
|
+
await this.refreshMcpServers();
|
|
518
|
+
return false;
|
|
519
|
+
}
|
|
520
|
+
await this.refreshMcpServers();
|
|
521
|
+
return true;
|
|
522
|
+
} catch {
|
|
523
|
+
await this.refreshMcpServers().catch(() => {});
|
|
524
|
+
return false;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
async getMcpTools(serverName) {
|
|
528
|
+
try {
|
|
529
|
+
const response = await this.io.fetch(`/api/mcp-servers/${encodeURIComponent(serverName)}/tools`, { credentials: "same-origin" });
|
|
530
|
+
if (!response.ok) return [];
|
|
531
|
+
return (await response.json()).tools ?? [];
|
|
532
|
+
} catch {
|
|
533
|
+
return [];
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
async saveMcpToken(serverName, token) {
|
|
537
|
+
try {
|
|
538
|
+
if (!(await this.io.fetch(`/api/mcp-servers/${encodeURIComponent(serverName)}/token`, {
|
|
539
|
+
method: "PUT",
|
|
540
|
+
credentials: "same-origin",
|
|
541
|
+
headers: { "content-type": "application/json" },
|
|
542
|
+
body: JSON.stringify({ token })
|
|
543
|
+
})).ok) return false;
|
|
544
|
+
await this.io.fetch(`/api/mcp-servers/${encodeURIComponent(serverName)}/probe`, {
|
|
545
|
+
method: "POST",
|
|
546
|
+
credentials: "same-origin"
|
|
547
|
+
}).catch(() => {});
|
|
548
|
+
await this.refreshMcpServers();
|
|
549
|
+
return true;
|
|
550
|
+
} catch {
|
|
551
|
+
return false;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
async startOAuthConnect(serverName, serverUrl) {
|
|
555
|
+
const redirectUri = `${globalThis.location?.origin ?? ""}/api/mcp/oauth/callback`;
|
|
556
|
+
try {
|
|
557
|
+
const response = await this.io.fetch("/api/mcp/oauth/start", {
|
|
558
|
+
method: "POST",
|
|
559
|
+
credentials: "same-origin",
|
|
560
|
+
headers: { "content-type": "application/json" },
|
|
561
|
+
body: JSON.stringify({
|
|
562
|
+
serverName,
|
|
563
|
+
serverUrl,
|
|
564
|
+
redirectUri
|
|
565
|
+
})
|
|
566
|
+
});
|
|
567
|
+
if (!response.ok) {
|
|
568
|
+
const data = await response.json().catch(() => ({}));
|
|
569
|
+
this.store.update((state) => {
|
|
570
|
+
state.mcpError = data.error ?? "OAuth start failed";
|
|
571
|
+
});
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
574
|
+
return (await response.json()).authorizationUrl;
|
|
575
|
+
} catch (error) {
|
|
576
|
+
this.store.update((state) => {
|
|
577
|
+
state.mcpError = messageOf(error);
|
|
578
|
+
});
|
|
579
|
+
return;
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
async completeOAuthConnect(code, state) {
|
|
583
|
+
try {
|
|
584
|
+
const response = await this.io.fetch("/api/mcp/oauth/complete", {
|
|
585
|
+
method: "POST",
|
|
586
|
+
credentials: "same-origin",
|
|
587
|
+
headers: { "content-type": "application/json" },
|
|
588
|
+
body: JSON.stringify({
|
|
589
|
+
code,
|
|
590
|
+
state
|
|
591
|
+
})
|
|
592
|
+
});
|
|
593
|
+
if (!response.ok) {
|
|
594
|
+
const data = await response.json().catch(() => ({}));
|
|
595
|
+
this.store.update((state) => {
|
|
596
|
+
state.mcpError = data.error ?? "OAuth complete failed";
|
|
597
|
+
});
|
|
598
|
+
return false;
|
|
599
|
+
}
|
|
600
|
+
return true;
|
|
601
|
+
} catch {
|
|
602
|
+
return false;
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
async clearMcpToken(serverName) {
|
|
606
|
+
await this.io.fetch(`/api/mcp-servers/${encodeURIComponent(serverName)}/token`, {
|
|
607
|
+
method: "DELETE",
|
|
608
|
+
credentials: "same-origin"
|
|
609
|
+
}).catch(() => {});
|
|
610
|
+
}
|
|
334
611
|
async copyUpgrade() {
|
|
335
612
|
try {
|
|
336
613
|
const version = this.store.getSnapshot().health?.version ?? "0.0.0";
|
|
@@ -370,7 +647,7 @@ window.__ModuleLoader__.load({
|
|
|
370
647
|
};
|
|
371
648
|
//#endregion
|
|
372
649
|
//#region \0dsh-edge-css:src/client/EdgeSettingsSection.module.css.mjs
|
|
373
|
-
const css = "._68Y4qa_section{gap:20px;max-width:720px;display:grid}._68Y4qa_section header h2,._68Y4qa_card h3{color:var(--dsw-alias-text-primary);margin:0}._68Y4qa_section header p,._68Y4qa_card p{color:var(--dsw-alias-label-secondary)}._68Y4qa_card{border:1px solid var(--dsw-alias-border-subtle);border-radius:12px;padding:18px}._68Y4qa_card dl{margin:12px 0}._68Y4qa_row{border-bottom:1px solid var(--dsw-alias-border-secondary);grid-template-columns:minmax(150px,1fr) minmax(0,2fr);gap:16px;padding:8px 0;display:grid}._68Y4qa_row:last-child{border-bottom:0}._68Y4qa_row dt{color:var(--dsw-alias-label-secondary)}._68Y4qa_row dd{overflow-wrap:anywhere;color:var(--dsw-alias-text-primary);margin:0}._68Y4qa_actions{flex-wrap:wrap;align-items:center;gap:12px;display:flex}._68Y4qa_actions a{color:var(--dsw-alias-brand-primary)}._68Y4qa_status{align-items:center;gap:8px;display:flex}._68Y4qa_notice{color:var(--dsw-alias-label-secondary)}._68Y4qa_error{color:var(--dsw-alias-state-error-primary)!important}@media (width<=560px){._68Y4qa_row{grid-template-columns:1fr;gap:4px}}";
|
|
650
|
+
const css = "._68Y4qa_section{gap:20px;max-width:720px;display:grid}._68Y4qa_section header h2,._68Y4qa_card h3{color:var(--dsw-alias-text-primary);margin:0}._68Y4qa_section header p,._68Y4qa_card p{color:var(--dsw-alias-label-secondary)}._68Y4qa_card{border:1px solid var(--dsw-alias-border-subtle);border-radius:12px;padding:18px}._68Y4qa_card dl{margin:12px 0}._68Y4qa_row{border-bottom:1px solid var(--dsw-alias-border-secondary);grid-template-columns:minmax(150px,1fr) minmax(0,2fr);gap:16px;padding:8px 0;display:grid}._68Y4qa_row:last-child{border-bottom:0}._68Y4qa_row dt{color:var(--dsw-alias-label-secondary)}._68Y4qa_row dd{overflow-wrap:anywhere;color:var(--dsw-alias-text-primary);margin:0}._68Y4qa_actions{flex-wrap:wrap;align-items:center;gap:12px;display:flex}._68Y4qa_actions a{color:var(--dsw-alias-brand-primary)}._68Y4qa_status{align-items:center;gap:8px;display:flex}._68Y4qa_notice{color:var(--dsw-alias-label-tertiary,var(--dsw-alias-label-secondary));font-size:13px}._68Y4qa_error{word-break:break-word;overflow-wrap:anywhere;font-size:13px;color:var(--dsw-alias-state-error-primary)!important}._68Y4qa_select{border:.5px solid var(--dsw-alias-border-l4,var(--dsw-alias-border-subtle));background:var(--dsw-alias-bg-layer-3,var(--dsw-alias-background-primary));color:var(--dsw-alias-label-primary,var(--dsw-alias-text-primary));height:34px;font:inherit;appearance:none;background-image:url(\"data:image/svg+xml,%3Csvg width='10' height='6' viewBox='0 0 10 6' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23999' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\");background-position:right 10px center;background-repeat:no-repeat;border-radius:8px;padding:0 28px 0 10px;font-size:13px;line-height:1.5}._68Y4qa_select:focus-visible{border-color:var(--dsw-alias-brand-primary);outline:none}._68Y4qa_input{border:.5px solid var(--dsw-alias-border-l4,var(--dsw-alias-border-subtle));background:var(--dsw-alias-bg-layer-3,var(--dsw-alias-background-primary));color:var(--dsw-alias-label-primary,var(--dsw-alias-text-primary));height:34px;font:inherit;box-sizing:border-box;border-radius:8px;width:100%;padding:0 12px;font-size:13px;line-height:1.5}._68Y4qa_input:focus-visible{border-color:var(--dsw-alias-brand-primary);outline:none}._68Y4qa_mcpList{flex-direction:column;gap:10px;margin:0;padding:0;list-style:none;display:flex}._68Y4qa_mcpCard{border:.5px solid var(--dsw-alias-border-l4,var(--dsw-alias-border-subtle));background:var(--dsw-alias-bg-layer-3,transparent);border-radius:16px;list-style:none;transition:border-color .16s,background .16s}._68Y4qa_mcpCard:hover{border-color:var(--dsw-alias-label-dimmed,#bbb)}._68Y4qa_mcpCardOpen{background:var(--dsw-alias-bg-layer-2,transparent);border-color:var(--dsw-alias-label-dimmed,#bbb)}._68Y4qa_mcpCardHeader{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}._68Y4qa_mcpCardHeader:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}._68Y4qa_mcpAvatar{background:var(--dsw-alias-brand-background,#eef2fe);width:32px;height:32px;color:var(--dsw-alias-brand-primary);border-radius:8px;flex-shrink:0;justify-content:center;align-items:center;font-size:14px;font-weight:600;display:flex}._68Y4qa_mcpCardTitleGroup{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}._68Y4qa_mcpCardName{color:var(--dsw-alias-label-primary,var(--dsw-alias-text-primary));margin:0;font-size:15px;font-weight:600;line-height:1.4}._68Y4qa_mcpCardSub{color:var(--dsw-alias-label-tertiary,var(--dsw-alias-label-secondary));align-items:center;gap:8px;margin:0;font-size:13px;line-height:1.5;display:flex}._68Y4qa_mcpChevron{color:var(--dsw-alias-label-tertiary,var(--dsw-alias-label-secondary));flex:none;transition:transform .16s}._68Y4qa_mcpChevronOpen{transform:rotate(180deg)}._68Y4qa_mcpChevron svg{display:block}._68Y4qa_mcpBadge{border-radius:4px;padding:1px 6px;font-size:11px;font-weight:500}._68Y4qa_mcpBadge[data-status=connected]{background:var(--dsw-alias-state-success-background,#ecfdf3);color:var(--dsw-alias-state-success-primary,#16a34a)}._68Y4qa_mcpBadge[data-status=error]{background:var(--dsw-alias-state-error-background,#fff0f0);color:var(--dsw-alias-state-error-primary,#dc2626)}._68Y4qa_mcpBadge[data-status=needs_reauth]{background:var(--dsw-alias-state-warning-background,#fff8e6);color:var(--dsw-alias-state-warning-primary,#d97706)}._68Y4qa_mcpBadge[data-status=unknown]{background:var(--dsw-alias-background-secondary,#f3f4f6);color:var(--dsw-alias-label-tertiary,var(--dsw-alias-label-secondary))}._68Y4qa_mcpCardBody{border-top:.5px solid var(--dsw-alias-border-l2,var(--dsw-alias-border-secondary));gap:12px;min-width:0;margin:0 16px;padding:12px 0 8px;display:grid}._68Y4qa_mcpFieldRow{grid-template-columns:140px 1fr;align-items:center;gap:12px;display:grid}._68Y4qa_mcpFieldLabel{color:var(--dsw-alias-label-tertiary,var(--dsw-alias-label-secondary));font-size:13px;line-height:1.5}._68Y4qa_mcpFieldValue{color:var(--dsw-alias-label-primary,var(--dsw-alias-text-primary));font-size:13px;line-height:1.5}._68Y4qa_mcpCardSuccess{color:var(--dsw-alias-state-success-primary,#16a34a);margin:0;padding:4px 0;font-size:12px;line-height:1.4}._68Y4qa_mcpCardError{color:var(--dsw-alias-state-error-primary,#dc2626);margin:0;padding:4px 0;font-size:12px;line-height:1.4}._68Y4qa_mcpCardActions{border-top:.5px solid var(--dsw-alias-border-l2,var(--dsw-alias-border-secondary));justify-content:flex-end;align-items:center;gap:8px;padding:12px 0 4px;display:flex}._68Y4qa_mcpAddTrigger{appearance:none;width:100%;font:inherit;cursor:pointer;border:.5px dashed var(--dsw-alias-border-l4,var(--dsw-alias-border-subtle));color:var(--dsw-alias-label-tertiary,var(--dsw-alias-label-secondary));background:0 0;border-radius:16px;justify-content:center;align-items:center;gap:6px;padding:14px 16px;font-size:13px;line-height:1.5;transition:border-color .16s,color .16s;display:flex}._68Y4qa_mcpAddTrigger:hover{border-color:var(--dsw-alias-label-dimmed,#bbb);color:var(--dsw-alias-label-primary,var(--dsw-alias-text-primary))}._68Y4qa_mcpAddTrigger:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}._68Y4qa_mcpToolList{flex-direction:column;gap:6px;display:flex}._68Y4qa_mcpToolItems{flex-direction:column;gap:0;min-width:0;max-height:300px;margin:4px 0 0;padding:0;list-style:none;display:flex;overflow-y:auto}._68Y4qa_mcpToolItem{border-bottom:.5px solid var(--dsw-alias-border-l2,var(--dsw-alias-border-secondary));flex-wrap:wrap;align-items:baseline;gap:4px 8px;padding:6px 0;display:flex}._68Y4qa_mcpToolItem:last-child{border-bottom:none}._68Y4qa_mcpToolName{font-family:var(--ds-font-family-code,monospace);color:var(--dsw-alias-label-primary,var(--dsw-alias-text-primary));font-size:12px}._68Y4qa_mcpToolDesc{color:var(--dsw-alias-label-tertiary,var(--dsw-alias-label-secondary));width:100%;font-size:12px;line-height:1.4}._68Y4qa_mcpAddForm{border:.5px solid var(--dsw-alias-border-l4,var(--dsw-alias-border-subtle));border-radius:16px;gap:14px;padding:16px;display:grid}._68Y4qa_mcpFormRow{grid-template-columns:1fr 1fr;gap:10px;display:grid}._68Y4qa_mcpFormActions{justify-content:flex-end;gap:8px;display:flex}@media (width<=560px){._68Y4qa_row{grid-template-columns:1fr;gap:4px}._68Y4qa_mcpFormRow{grid-template-columns:1fr}._68Y4qa_mcpFieldRow{grid-template-columns:1fr;gap:4px}}";
|
|
374
651
|
const tagId = "dsh-edge-client-ui/src/client/EdgeSettingsSection.module.css";
|
|
375
652
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
376
653
|
const tag = document.createElement("style");
|
|
@@ -383,9 +660,38 @@ window.__ModuleLoader__.load({
|
|
|
383
660
|
"actions": "_68Y4qa_actions",
|
|
384
661
|
"card": "_68Y4qa_card",
|
|
385
662
|
"error": "_68Y4qa_error",
|
|
663
|
+
"input": "_68Y4qa_input",
|
|
664
|
+
"mcpAddForm": "_68Y4qa_mcpAddForm",
|
|
665
|
+
"mcpAddTrigger": "_68Y4qa_mcpAddTrigger",
|
|
666
|
+
"mcpAvatar": "_68Y4qa_mcpAvatar",
|
|
667
|
+
"mcpBadge": "_68Y4qa_mcpBadge",
|
|
668
|
+
"mcpCard": "_68Y4qa_mcpCard",
|
|
669
|
+
"mcpCardActions": "_68Y4qa_mcpCardActions",
|
|
670
|
+
"mcpCardBody": "_68Y4qa_mcpCardBody",
|
|
671
|
+
"mcpCardError": "_68Y4qa_mcpCardError",
|
|
672
|
+
"mcpCardHeader": "_68Y4qa_mcpCardHeader",
|
|
673
|
+
"mcpCardName": "_68Y4qa_mcpCardName",
|
|
674
|
+
"mcpCardOpen": "_68Y4qa_mcpCardOpen",
|
|
675
|
+
"mcpCardSub": "_68Y4qa_mcpCardSub",
|
|
676
|
+
"mcpCardSuccess": "_68Y4qa_mcpCardSuccess",
|
|
677
|
+
"mcpCardTitleGroup": "_68Y4qa_mcpCardTitleGroup",
|
|
678
|
+
"mcpChevron": "_68Y4qa_mcpChevron",
|
|
679
|
+
"mcpChevronOpen": "_68Y4qa_mcpChevronOpen",
|
|
680
|
+
"mcpFieldLabel": "_68Y4qa_mcpFieldLabel",
|
|
681
|
+
"mcpFieldRow": "_68Y4qa_mcpFieldRow",
|
|
682
|
+
"mcpFieldValue": "_68Y4qa_mcpFieldValue",
|
|
683
|
+
"mcpFormActions": "_68Y4qa_mcpFormActions",
|
|
684
|
+
"mcpFormRow": "_68Y4qa_mcpFormRow",
|
|
685
|
+
"mcpList": "_68Y4qa_mcpList",
|
|
686
|
+
"mcpToolDesc": "_68Y4qa_mcpToolDesc",
|
|
687
|
+
"mcpToolItem": "_68Y4qa_mcpToolItem",
|
|
688
|
+
"mcpToolItems": "_68Y4qa_mcpToolItems",
|
|
689
|
+
"mcpToolList": "_68Y4qa_mcpToolList",
|
|
690
|
+
"mcpToolName": "_68Y4qa_mcpToolName",
|
|
386
691
|
"notice": "_68Y4qa_notice",
|
|
387
692
|
"row": "_68Y4qa_row",
|
|
388
693
|
"section": "_68Y4qa_section",
|
|
694
|
+
"select": "_68Y4qa_select",
|
|
389
695
|
"status": "_68Y4qa_status"
|
|
390
696
|
};
|
|
391
697
|
//#endregion
|
|
@@ -397,7 +703,7 @@ window.__ModuleLoader__.load({
|
|
|
397
703
|
});
|
|
398
704
|
}
|
|
399
705
|
function EdgeSettingsSection(props) {
|
|
400
|
-
const { useEdgeSettings, load, copyUpgrade, signOut, t } = props;
|
|
706
|
+
const { useEdgeSettings, load, copyUpgrade, signOut, setApprovalMode, t } = props;
|
|
401
707
|
(0, react.useEffect)(() => {
|
|
402
708
|
load();
|
|
403
709
|
}, [load]);
|
|
@@ -494,6 +800,44 @@ window.__ModuleLoader__.load({
|
|
|
494
800
|
children: [
|
|
495
801
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", { children: t("title") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("intro") })] }),
|
|
496
802
|
deploymentDetails,
|
|
803
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
804
|
+
className: EdgeSettingsSection_module_css_default.card,
|
|
805
|
+
"aria-labelledby": "edge-approval-title",
|
|
806
|
+
children: [
|
|
807
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
808
|
+
id: "edge-approval-title",
|
|
809
|
+
children: t("toolPermissions")
|
|
810
|
+
}),
|
|
811
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dl", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Row, {
|
|
812
|
+
label: t("approvalMode"),
|
|
813
|
+
value: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
814
|
+
className: EdgeSettingsSection_module_css_default.select,
|
|
815
|
+
value: state.approvalMode,
|
|
816
|
+
disabled: state.approvalSaving || state.status !== "ready",
|
|
817
|
+
"aria-label": t("approvalMode"),
|
|
818
|
+
onChange: (e) => {
|
|
819
|
+
setApprovalMode(e.target.value);
|
|
820
|
+
},
|
|
821
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
822
|
+
value: "ask",
|
|
823
|
+
children: t("approvalAsk")
|
|
824
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
825
|
+
value: "never",
|
|
826
|
+
children: t("approvalNever")
|
|
827
|
+
})]
|
|
828
|
+
})
|
|
829
|
+
}) }),
|
|
830
|
+
state.approvalSaved ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
831
|
+
className: EdgeSettingsSection_module_css_default.status,
|
|
832
|
+
children: t("approvalSaved")
|
|
833
|
+
}) : null,
|
|
834
|
+
state.approvalError !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
835
|
+
className: EdgeSettingsSection_module_css_default.error,
|
|
836
|
+
role: "alert",
|
|
837
|
+
children: t("approvalError")
|
|
838
|
+
}) : null
|
|
839
|
+
]
|
|
840
|
+
}),
|
|
497
841
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
498
842
|
className: EdgeSettingsSection_module_css_default.card,
|
|
499
843
|
"aria-labelledby": "edge-owner-title",
|
|
@@ -523,6 +867,467 @@ window.__ModuleLoader__.load({
|
|
|
523
867
|
});
|
|
524
868
|
}
|
|
525
869
|
//#endregion
|
|
870
|
+
//#region ../../../packages/client/ui-edge/src/client/EdgeMcpSection.tsx
|
|
871
|
+
function ChevronIcon({ expanded }) {
|
|
872
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
873
|
+
className: `${EdgeSettingsSection_module_css_default.mcpChevron}${expanded ? ` ${EdgeSettingsSection_module_css_default.mcpChevronOpen}` : ""}`,
|
|
874
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
875
|
+
width: "16",
|
|
876
|
+
height: "16",
|
|
877
|
+
viewBox: "0 0 16 16",
|
|
878
|
+
fill: "none",
|
|
879
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
880
|
+
d: "M4 6l4 4 4-4",
|
|
881
|
+
stroke: "currentColor",
|
|
882
|
+
strokeWidth: "1.5",
|
|
883
|
+
strokeLinecap: "round",
|
|
884
|
+
strokeLinejoin: "round"
|
|
885
|
+
})
|
|
886
|
+
})
|
|
887
|
+
});
|
|
888
|
+
}
|
|
889
|
+
function McpConnectorCard({ server: s, saving, disabled, expanded, onToggle, onRemove, onSetToolPolicy, onProbe, onGetTools, onOAuthConnect, connecting, t }) {
|
|
890
|
+
const hasTools = s.toolCount !== void 0 && s.toolCount > 0;
|
|
891
|
+
const [probing, setProbing] = (0, react.useState)(false);
|
|
892
|
+
const [tools, setTools] = (0, react.useState)(null);
|
|
893
|
+
const [toolsLoading, setToolsLoading] = (0, react.useState)(false);
|
|
894
|
+
(0, react.useEffect)(() => {
|
|
895
|
+
if (expanded && hasTools && tools === null && !toolsLoading) {
|
|
896
|
+
setToolsLoading(true);
|
|
897
|
+
onGetTools().then((t) => {
|
|
898
|
+
setTools(t);
|
|
899
|
+
setToolsLoading(false);
|
|
900
|
+
});
|
|
901
|
+
}
|
|
902
|
+
if (!expanded) setTools(null);
|
|
903
|
+
}, [expanded, hasTools]);
|
|
904
|
+
const authLabel = s.auth?.type === "oauth" ? "OAuth 2.1" : s.auth?.type === "bearer" ? "Bearer Token" : t("mcpAuthNone");
|
|
905
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
906
|
+
className: `${EdgeSettingsSection_module_css_default.mcpCard}${expanded ? ` ${EdgeSettingsSection_module_css_default.mcpCardOpen}` : ""}`,
|
|
907
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
908
|
+
type: "button",
|
|
909
|
+
className: EdgeSettingsSection_module_css_default.mcpCardHeader,
|
|
910
|
+
"aria-expanded": expanded,
|
|
911
|
+
onClick: onToggle,
|
|
912
|
+
children: [
|
|
913
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
914
|
+
className: EdgeSettingsSection_module_css_default.mcpAvatar,
|
|
915
|
+
children: s.serverName.charAt(0).toUpperCase()
|
|
916
|
+
}),
|
|
917
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
918
|
+
className: EdgeSettingsSection_module_css_default.mcpCardTitleGroup,
|
|
919
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
920
|
+
className: EdgeSettingsSection_module_css_default.mcpCardName,
|
|
921
|
+
children: s.serverName
|
|
922
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
923
|
+
className: EdgeSettingsSection_module_css_default.mcpCardSub,
|
|
924
|
+
children: s.auth?.type !== void 0 && s.auth.type !== "none" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
925
|
+
className: EdgeSettingsSection_module_css_default.mcpBadge,
|
|
926
|
+
"data-status": "unknown",
|
|
927
|
+
children: s.auth.type.toUpperCase()
|
|
928
|
+
}) : null
|
|
929
|
+
})]
|
|
930
|
+
}),
|
|
931
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChevronIcon, { expanded })
|
|
932
|
+
]
|
|
933
|
+
}), expanded ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
934
|
+
className: EdgeSettingsSection_module_css_default.mcpCardBody,
|
|
935
|
+
children: [
|
|
936
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
937
|
+
className: EdgeSettingsSection_module_css_default.mcpFieldRow,
|
|
938
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
939
|
+
className: EdgeSettingsSection_module_css_default.mcpFieldLabel,
|
|
940
|
+
children: "URL"
|
|
941
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
|
|
942
|
+
className: EdgeSettingsSection_module_css_default.mcpFieldValue,
|
|
943
|
+
style: {
|
|
944
|
+
fontSize: 12,
|
|
945
|
+
wordBreak: "break-all"
|
|
946
|
+
},
|
|
947
|
+
children: s.url
|
|
948
|
+
})]
|
|
949
|
+
}),
|
|
950
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
951
|
+
className: EdgeSettingsSection_module_css_default.mcpFieldRow,
|
|
952
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
953
|
+
className: EdgeSettingsSection_module_css_default.mcpFieldLabel,
|
|
954
|
+
children: t("mcpAuthLabel")
|
|
955
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
956
|
+
className: EdgeSettingsSection_module_css_default.mcpFieldValue,
|
|
957
|
+
children: authLabel
|
|
958
|
+
})]
|
|
959
|
+
}),
|
|
960
|
+
s.serverInfo?.name !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
961
|
+
className: EdgeSettingsSection_module_css_default.mcpFieldRow,
|
|
962
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
963
|
+
className: EdgeSettingsSection_module_css_default.mcpFieldLabel,
|
|
964
|
+
children: t("mcpServerInfo")
|
|
965
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
966
|
+
className: EdgeSettingsSection_module_css_default.mcpFieldValue,
|
|
967
|
+
children: [s.serverInfo.name, s.serverInfo.version !== void 0 ? ` v${s.serverInfo.version}` : ""]
|
|
968
|
+
})]
|
|
969
|
+
}) : null,
|
|
970
|
+
s.status === "connected" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
971
|
+
className: EdgeSettingsSection_module_css_default.mcpCardSuccess,
|
|
972
|
+
children: [
|
|
973
|
+
s.toolCount ?? 0,
|
|
974
|
+
" ",
|
|
975
|
+
t("mcpTools"),
|
|
976
|
+
" · ",
|
|
977
|
+
t("mcpConnected")
|
|
978
|
+
]
|
|
979
|
+
}) : s.status === "error" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
980
|
+
className: EdgeSettingsSection_module_css_default.mcpCardError,
|
|
981
|
+
children: t("mcpConnectionFailed")
|
|
982
|
+
}) : null,
|
|
983
|
+
s.status === "connected" || hasTools ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
984
|
+
className: EdgeSettingsSection_module_css_default.mcpFieldRow,
|
|
985
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
986
|
+
className: EdgeSettingsSection_module_css_default.mcpFieldLabel,
|
|
987
|
+
children: t("mcpToolPolicy")
|
|
988
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
989
|
+
className: EdgeSettingsSection_module_css_default.select,
|
|
990
|
+
value: s.toolPolicy?.mode ?? "read_only",
|
|
991
|
+
disabled: saving || disabled,
|
|
992
|
+
"aria-label": t("mcpToolPolicy"),
|
|
993
|
+
onChange: (e) => onSetToolPolicy(e.target.value),
|
|
994
|
+
children: [
|
|
995
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
996
|
+
value: "approve_all",
|
|
997
|
+
children: t("mcpPolicyApproveAll")
|
|
998
|
+
}),
|
|
999
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1000
|
+
value: "read_only",
|
|
1001
|
+
children: t("mcpPolicyReadOnly")
|
|
1002
|
+
}),
|
|
1003
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1004
|
+
value: "allow_all",
|
|
1005
|
+
children: t("mcpPolicyAllowAll")
|
|
1006
|
+
})
|
|
1007
|
+
]
|
|
1008
|
+
})]
|
|
1009
|
+
}) : null,
|
|
1010
|
+
hasTools && tools !== null && tools.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1011
|
+
className: EdgeSettingsSection_module_css_default.mcpToolList,
|
|
1012
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1013
|
+
className: EdgeSettingsSection_module_css_default.mcpFieldLabel,
|
|
1014
|
+
children: [
|
|
1015
|
+
t("mcpToolsLabel"),
|
|
1016
|
+
" (",
|
|
1017
|
+
tools.length,
|
|
1018
|
+
")"
|
|
1019
|
+
]
|
|
1020
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
|
|
1021
|
+
className: EdgeSettingsSection_module_css_default.mcpToolItems,
|
|
1022
|
+
children: tools.map((tool) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
1023
|
+
className: EdgeSettingsSection_module_css_default.mcpToolItem,
|
|
1024
|
+
children: [
|
|
1025
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
|
|
1026
|
+
className: EdgeSettingsSection_module_css_default.mcpToolName,
|
|
1027
|
+
children: tool.name
|
|
1028
|
+
}),
|
|
1029
|
+
tool.readOnly === true ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1030
|
+
className: EdgeSettingsSection_module_css_default.mcpBadge,
|
|
1031
|
+
"data-status": "connected",
|
|
1032
|
+
children: t("mcpRead")
|
|
1033
|
+
}) : tool.readOnly === false ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1034
|
+
className: EdgeSettingsSection_module_css_default.mcpBadge,
|
|
1035
|
+
"data-status": "error",
|
|
1036
|
+
children: t("mcpWrite")
|
|
1037
|
+
}) : null,
|
|
1038
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1039
|
+
className: EdgeSettingsSection_module_css_default.mcpToolDesc,
|
|
1040
|
+
children: tool.description
|
|
1041
|
+
})
|
|
1042
|
+
]
|
|
1043
|
+
}, tool.publicName))
|
|
1044
|
+
})]
|
|
1045
|
+
}) : toolsLoading ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1046
|
+
className: EdgeSettingsSection_module_css_default.mcpFieldLabel,
|
|
1047
|
+
children: t("loading")
|
|
1048
|
+
}) : null,
|
|
1049
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1050
|
+
className: EdgeSettingsSection_module_css_default.mcpCardActions,
|
|
1051
|
+
children: [s.auth?.type === "oauth" && s.status !== "connected" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1052
|
+
variant: "outline",
|
|
1053
|
+
size: "sm",
|
|
1054
|
+
disabled: saving || disabled || connecting,
|
|
1055
|
+
onClick: onOAuthConnect,
|
|
1056
|
+
children: connecting ? t("mcpConnecting") : s.status === "needs_reauth" ? t("mcpReconnect") : t("mcpConnect")
|
|
1057
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1058
|
+
variant: "outline",
|
|
1059
|
+
size: "sm",
|
|
1060
|
+
disabled: saving || disabled || probing,
|
|
1061
|
+
onClick: () => {
|
|
1062
|
+
setProbing(true);
|
|
1063
|
+
onProbe().then(() => onGetTools().then(setTools)).finally(() => setProbing(false));
|
|
1064
|
+
},
|
|
1065
|
+
children: probing ? t("mcpProbing") : t("mcpRefresh")
|
|
1066
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1067
|
+
variant: "outline",
|
|
1068
|
+
size: "sm",
|
|
1069
|
+
disabled: saving || disabled,
|
|
1070
|
+
onClick: onRemove,
|
|
1071
|
+
children: t("mcpRemove")
|
|
1072
|
+
})]
|
|
1073
|
+
})
|
|
1074
|
+
]
|
|
1075
|
+
}) : null]
|
|
1076
|
+
});
|
|
1077
|
+
}
|
|
1078
|
+
function EdgeMcpSection(props) {
|
|
1079
|
+
const { useEdgeSettings, load, saveMcpServers, saveMcpToken, setMcpToolPolicy, probeMcpServer, getMcpTools, startOAuthConnect, t } = props;
|
|
1080
|
+
(0, react.useEffect)(() => {
|
|
1081
|
+
load();
|
|
1082
|
+
}, [load]);
|
|
1083
|
+
const state = useEdgeSettings((snapshot) => snapshot);
|
|
1084
|
+
const servers = state.mcpServers;
|
|
1085
|
+
const saving = state.mcpSaving;
|
|
1086
|
+
const disabled = state.status !== "ready" || !state.mcpLoaded;
|
|
1087
|
+
const [expandedServer, setExpandedServer] = (0, react.useState)(null);
|
|
1088
|
+
const [connectingServer, setConnectingServer] = (0, react.useState)(null);
|
|
1089
|
+
const [popupError, setPopupError] = (0, react.useState)(null);
|
|
1090
|
+
const [showAddForm, setShowAddForm] = (0, react.useState)(false);
|
|
1091
|
+
(0, react.useEffect)(() => {
|
|
1092
|
+
const handler = (e) => {
|
|
1093
|
+
if (e.data?.type === "mcp-oauth-complete") setConnectingServer(null);
|
|
1094
|
+
};
|
|
1095
|
+
globalThis.addEventListener?.("message", handler);
|
|
1096
|
+
return () => globalThis.removeEventListener?.("message", handler);
|
|
1097
|
+
}, []);
|
|
1098
|
+
const [draft, setDraft] = (0, react.useState)({
|
|
1099
|
+
serverName: "",
|
|
1100
|
+
url: "",
|
|
1101
|
+
authType: "none",
|
|
1102
|
+
token: ""
|
|
1103
|
+
});
|
|
1104
|
+
const addServer = (0, react.useCallback)(() => {
|
|
1105
|
+
if (draft.serverName.trim() === "" || draft.url.trim() === "") return;
|
|
1106
|
+
const entry = {
|
|
1107
|
+
serverName: draft.serverName.trim(),
|
|
1108
|
+
url: draft.url.trim(),
|
|
1109
|
+
auth: { type: draft.authType }
|
|
1110
|
+
};
|
|
1111
|
+
(async () => {
|
|
1112
|
+
const name = draft.serverName.trim();
|
|
1113
|
+
if (!/^[A-Za-z0-9_-]{1,32}$/u.test(name)) return;
|
|
1114
|
+
try {
|
|
1115
|
+
new URL(draft.url.trim());
|
|
1116
|
+
} catch {
|
|
1117
|
+
return;
|
|
1118
|
+
}
|
|
1119
|
+
if (servers.some((s) => s.serverName === name)) return;
|
|
1120
|
+
if (draft.authType === "bearer" && draft.token.trim() !== "") {
|
|
1121
|
+
if (!await saveMcpToken(name, draft.token.trim())) return;
|
|
1122
|
+
}
|
|
1123
|
+
if (!await saveMcpServers([...servers, entry])) return;
|
|
1124
|
+
const addedName = name;
|
|
1125
|
+
const addedUrl = draft.url.trim();
|
|
1126
|
+
const addedAuth = draft.authType;
|
|
1127
|
+
setDraft({
|
|
1128
|
+
serverName: "",
|
|
1129
|
+
url: "",
|
|
1130
|
+
authType: "none",
|
|
1131
|
+
token: ""
|
|
1132
|
+
});
|
|
1133
|
+
setShowAddForm(false);
|
|
1134
|
+
setExpandedServer(addedName);
|
|
1135
|
+
if (addedAuth === "oauth") {
|
|
1136
|
+
setConnectingServer(addedName);
|
|
1137
|
+
const authUrl = await startOAuthConnect(addedName, addedUrl);
|
|
1138
|
+
if (authUrl === void 0) setConnectingServer(null);
|
|
1139
|
+
else {
|
|
1140
|
+
const popup = globalThis.open(authUrl, "_blank", "width=600,height=700");
|
|
1141
|
+
if (!popup) {
|
|
1142
|
+
setConnectingServer(null);
|
|
1143
|
+
setPopupError(addedName);
|
|
1144
|
+
} else {
|
|
1145
|
+
const check = setInterval(() => {
|
|
1146
|
+
if (popup.closed) {
|
|
1147
|
+
clearInterval(check);
|
|
1148
|
+
setConnectingServer((c) => c === addedName ? null : c);
|
|
1149
|
+
}
|
|
1150
|
+
}, 500);
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
})();
|
|
1155
|
+
}, [
|
|
1156
|
+
draft,
|
|
1157
|
+
servers,
|
|
1158
|
+
saveMcpServers,
|
|
1159
|
+
saveMcpToken
|
|
1160
|
+
]);
|
|
1161
|
+
const removeServer = (0, react.useCallback)((name) => {
|
|
1162
|
+
saveMcpServers(servers.filter((s) => s.serverName !== name));
|
|
1163
|
+
if (expandedServer === name) setExpandedServer(null);
|
|
1164
|
+
}, [
|
|
1165
|
+
servers,
|
|
1166
|
+
saveMcpServers,
|
|
1167
|
+
expandedServer
|
|
1168
|
+
]);
|
|
1169
|
+
if (state.status === "idle" || state.status === "loading") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1170
|
+
className: EdgeSettingsSection_module_css_default.section,
|
|
1171
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1172
|
+
className: EdgeSettingsSection_module_css_default.notice,
|
|
1173
|
+
children: t("loading")
|
|
1174
|
+
})
|
|
1175
|
+
});
|
|
1176
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1177
|
+
className: EdgeSettingsSection_module_css_default.section,
|
|
1178
|
+
children: [
|
|
1179
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", { children: t("mcpServers") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1180
|
+
style: { margin: "4px 0 0" },
|
|
1181
|
+
children: t("mcpIntro")
|
|
1182
|
+
})] }),
|
|
1183
|
+
servers.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
|
|
1184
|
+
className: EdgeSettingsSection_module_css_default.mcpList,
|
|
1185
|
+
children: servers.map((s) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(McpConnectorCard, {
|
|
1186
|
+
server: s,
|
|
1187
|
+
saving,
|
|
1188
|
+
disabled,
|
|
1189
|
+
expanded: expandedServer === s.serverName,
|
|
1190
|
+
onToggle: () => setExpandedServer((prev) => prev === s.serverName ? null : s.serverName),
|
|
1191
|
+
onRemove: () => removeServer(s.serverName),
|
|
1192
|
+
onSetToolPolicy: (mode) => {
|
|
1193
|
+
setMcpToolPolicy(s.serverName, mode);
|
|
1194
|
+
},
|
|
1195
|
+
onProbe: () => probeMcpServer(s.serverName),
|
|
1196
|
+
onGetTools: () => getMcpTools(s.serverName),
|
|
1197
|
+
onOAuthConnect: () => {
|
|
1198
|
+
setConnectingServer(s.serverName);
|
|
1199
|
+
setPopupError(null);
|
|
1200
|
+
startOAuthConnect(s.serverName, s.url).then((authUrl) => {
|
|
1201
|
+
if (authUrl === void 0) {
|
|
1202
|
+
setConnectingServer(null);
|
|
1203
|
+
return;
|
|
1204
|
+
}
|
|
1205
|
+
const popup = globalThis.open(authUrl, "_blank", "width=600,height=700");
|
|
1206
|
+
if (!popup) {
|
|
1207
|
+
setConnectingServer(null);
|
|
1208
|
+
setPopupError(s.serverName);
|
|
1209
|
+
return;
|
|
1210
|
+
}
|
|
1211
|
+
const check = setInterval(() => {
|
|
1212
|
+
if (popup.closed) {
|
|
1213
|
+
clearInterval(check);
|
|
1214
|
+
setConnectingServer((c) => c === s.serverName ? null : c);
|
|
1215
|
+
}
|
|
1216
|
+
}, 500);
|
|
1217
|
+
});
|
|
1218
|
+
},
|
|
1219
|
+
connecting: connectingServer === s.serverName,
|
|
1220
|
+
t
|
|
1221
|
+
}) }, s.serverName))
|
|
1222
|
+
}) : null,
|
|
1223
|
+
!showAddForm ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1224
|
+
type: "button",
|
|
1225
|
+
className: EdgeSettingsSection_module_css_default.mcpAddTrigger,
|
|
1226
|
+
disabled: saving || disabled,
|
|
1227
|
+
onClick: () => setShowAddForm(true),
|
|
1228
|
+
children: ["+ ", t("mcpAddServer")]
|
|
1229
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1230
|
+
className: EdgeSettingsSection_module_css_default.mcpAddForm,
|
|
1231
|
+
children: [
|
|
1232
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1233
|
+
className: EdgeSettingsSection_module_css_default.mcpFormRow,
|
|
1234
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1235
|
+
className: EdgeSettingsSection_module_css_default.input,
|
|
1236
|
+
placeholder: t("mcpNamePlaceholder"),
|
|
1237
|
+
value: draft.serverName,
|
|
1238
|
+
disabled: saving || disabled,
|
|
1239
|
+
onChange: (e) => setDraft((d) => ({
|
|
1240
|
+
...d,
|
|
1241
|
+
serverName: e.target.value
|
|
1242
|
+
}))
|
|
1243
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1244
|
+
className: EdgeSettingsSection_module_css_default.input,
|
|
1245
|
+
placeholder: t("mcpUrlPlaceholder"),
|
|
1246
|
+
value: draft.url,
|
|
1247
|
+
disabled: saving || disabled,
|
|
1248
|
+
onChange: (e) => setDraft((d) => ({
|
|
1249
|
+
...d,
|
|
1250
|
+
url: e.target.value
|
|
1251
|
+
}))
|
|
1252
|
+
})]
|
|
1253
|
+
}),
|
|
1254
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1255
|
+
className: EdgeSettingsSection_module_css_default.mcpFormRow,
|
|
1256
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
1257
|
+
className: EdgeSettingsSection_module_css_default.select,
|
|
1258
|
+
style: { width: "100%" },
|
|
1259
|
+
value: draft.authType,
|
|
1260
|
+
disabled: saving || disabled,
|
|
1261
|
+
"aria-label": "Auth type",
|
|
1262
|
+
onChange: (e) => setDraft((d) => ({
|
|
1263
|
+
...d,
|
|
1264
|
+
authType: e.target.value
|
|
1265
|
+
})),
|
|
1266
|
+
children: [
|
|
1267
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1268
|
+
value: "none",
|
|
1269
|
+
children: t("mcpAuthNone")
|
|
1270
|
+
}),
|
|
1271
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1272
|
+
value: "bearer",
|
|
1273
|
+
children: t("mcpAuthBearer")
|
|
1274
|
+
}),
|
|
1275
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1276
|
+
value: "oauth",
|
|
1277
|
+
children: t("mcpAuthOAuth")
|
|
1278
|
+
})
|
|
1279
|
+
]
|
|
1280
|
+
}), draft.authType === "bearer" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1281
|
+
className: EdgeSettingsSection_module_css_default.input,
|
|
1282
|
+
type: "password",
|
|
1283
|
+
placeholder: t("mcpTokenPlaceholder"),
|
|
1284
|
+
value: draft.token,
|
|
1285
|
+
disabled: saving || disabled,
|
|
1286
|
+
onChange: (e) => setDraft((d) => ({
|
|
1287
|
+
...d,
|
|
1288
|
+
token: e.target.value
|
|
1289
|
+
}))
|
|
1290
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {})]
|
|
1291
|
+
}),
|
|
1292
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1293
|
+
className: EdgeSettingsSection_module_css_default.mcpFormActions,
|
|
1294
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1295
|
+
variant: "outline",
|
|
1296
|
+
size: "sm",
|
|
1297
|
+
onClick: () => {
|
|
1298
|
+
setShowAddForm(false);
|
|
1299
|
+
setDraft({
|
|
1300
|
+
serverName: "",
|
|
1301
|
+
url: "",
|
|
1302
|
+
authType: "none",
|
|
1303
|
+
token: ""
|
|
1304
|
+
});
|
|
1305
|
+
},
|
|
1306
|
+
children: t("mcpCancel")
|
|
1307
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1308
|
+
variant: "outline",
|
|
1309
|
+
size: "sm",
|
|
1310
|
+
disabled: saving || disabled || draft.serverName.trim() === "" || draft.url.trim() === "" || draft.authType === "bearer" && draft.token.trim() === "",
|
|
1311
|
+
onClick: addServer,
|
|
1312
|
+
children: t("mcpAdd")
|
|
1313
|
+
})]
|
|
1314
|
+
})
|
|
1315
|
+
]
|
|
1316
|
+
}),
|
|
1317
|
+
popupError !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1318
|
+
className: EdgeSettingsSection_module_css_default.error,
|
|
1319
|
+
role: "alert",
|
|
1320
|
+
children: t("mcpPopupBlocked")
|
|
1321
|
+
}) : null,
|
|
1322
|
+
state.mcpError !== void 0 && popupError === null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1323
|
+
className: EdgeSettingsSection_module_css_default.error,
|
|
1324
|
+
role: "alert",
|
|
1325
|
+
children: state.mcpError
|
|
1326
|
+
}) : null
|
|
1327
|
+
]
|
|
1328
|
+
});
|
|
1329
|
+
}
|
|
1330
|
+
//#endregion
|
|
526
1331
|
//#region ../../../packages/client/ui-edge/src/client/locales.ts
|
|
527
1332
|
/** English copy is the key-set source of truth for the Edge settings page. */
|
|
528
1333
|
const en = {
|
|
@@ -556,7 +1361,48 @@ window.__ModuleLoader__.load({
|
|
|
556
1361
|
ownerIntro: "Signing out clears this browser’s owner session. Your deployment and data remain unchanged.",
|
|
557
1362
|
signOut: "Sign out",
|
|
558
1363
|
signingOut: "Signing out…",
|
|
559
|
-
signOutFailed: "Could not sign out. Try again."
|
|
1364
|
+
signOutFailed: "Could not sign out. Try again.",
|
|
1365
|
+
toolPermissions: "Tool permissions",
|
|
1366
|
+
approvalMode: "Web fetch tools",
|
|
1367
|
+
approvalAsk: "Always ask before running",
|
|
1368
|
+
approvalNever: "Trust all (no confirmation)",
|
|
1369
|
+
approvalSaved: "Saved",
|
|
1370
|
+
approvalError: "Could not save setting.",
|
|
1371
|
+
mcpServers: "MCP Connectors",
|
|
1372
|
+
mcpIntro: "Connect external tool servers to extend your agent with additional capabilities.",
|
|
1373
|
+
mcpEmpty: "No MCP servers configured.",
|
|
1374
|
+
mcpNamePlaceholder: "Server name (e.g. github)",
|
|
1375
|
+
mcpUrlPlaceholder: "Endpoint URL (e.g. https://mcp.example.com/sse)",
|
|
1376
|
+
mcpAdd: "Add server",
|
|
1377
|
+
mcpRemove: "Remove",
|
|
1378
|
+
mcpAuthNone: "No auth",
|
|
1379
|
+
mcpAuthBearer: "Bearer",
|
|
1380
|
+
mcpTokenPlaceholder: "Bearer token",
|
|
1381
|
+
mcpTokenSaved: "Token saved",
|
|
1382
|
+
mcpAuthOAuth: "OAuth",
|
|
1383
|
+
mcpConnect: "Connect",
|
|
1384
|
+
mcpReconnect: "Reconnect",
|
|
1385
|
+
mcpConnected: "connected",
|
|
1386
|
+
mcpNeedsReauth: "needs reconnect",
|
|
1387
|
+
mcpError: "connection error",
|
|
1388
|
+
mcpTools: "tools",
|
|
1389
|
+
mcpToolPolicy: "Tool permissions",
|
|
1390
|
+
mcpPolicyApproveAll: "Ask before every call",
|
|
1391
|
+
mcpPolicyReadOnly: "Allow reads, ask for writes",
|
|
1392
|
+
mcpPolicyAllowAll: "Trust all (no confirmation)",
|
|
1393
|
+
mcpNav: "MCP Connectors",
|
|
1394
|
+
mcpAddServer: "Add connector",
|
|
1395
|
+
mcpCancel: "Cancel",
|
|
1396
|
+
mcpAuthLabel: "Authentication",
|
|
1397
|
+
mcpServerInfo: "Server",
|
|
1398
|
+
mcpConnecting: "Connecting…",
|
|
1399
|
+
mcpPopupBlocked: "Pop-up blocked by browser. Please allow pop-ups for this site and try again.",
|
|
1400
|
+
mcpConnectionFailed: "Connection failed. Check the URL and authentication type.",
|
|
1401
|
+
mcpRefresh: "Refresh",
|
|
1402
|
+
mcpProbing: "Refreshing…",
|
|
1403
|
+
mcpToolsLabel: "Tools",
|
|
1404
|
+
mcpRead: "read",
|
|
1405
|
+
mcpWrite: "write"
|
|
560
1406
|
};
|
|
561
1407
|
/** Simplified Chinese copy for the Edge settings page. */
|
|
562
1408
|
const zh = {
|
|
@@ -590,7 +1436,48 @@ window.__ModuleLoader__.load({
|
|
|
590
1436
|
ownerIntro: "退出只会清除此浏览器的 Owner 会话,不会改变部署或数据。",
|
|
591
1437
|
signOut: "退出登录",
|
|
592
1438
|
signingOut: "正在退出…",
|
|
593
|
-
signOutFailed: "退出失败,请重试。"
|
|
1439
|
+
signOutFailed: "退出失败,请重试。",
|
|
1440
|
+
toolPermissions: "工具权限",
|
|
1441
|
+
approvalMode: "Web fetch 工具",
|
|
1442
|
+
approvalAsk: "每次都询问",
|
|
1443
|
+
approvalNever: "全部信任(不询问)",
|
|
1444
|
+
approvalSaved: "已保存",
|
|
1445
|
+
approvalError: "无法保存设置。",
|
|
1446
|
+
mcpServers: "MCP 连接器",
|
|
1447
|
+
mcpIntro: "连接外部工具服务器,为 Agent 扩展更多能力。",
|
|
1448
|
+
mcpEmpty: "尚未配置 MCP 服务器。",
|
|
1449
|
+
mcpNamePlaceholder: "服务器名称(如 github)",
|
|
1450
|
+
mcpUrlPlaceholder: "端点 URL(如 https://mcp.example.com/sse)",
|
|
1451
|
+
mcpAdd: "添加服务器",
|
|
1452
|
+
mcpRemove: "移除",
|
|
1453
|
+
mcpAuthNone: "无认证",
|
|
1454
|
+
mcpAuthBearer: "Bearer Token",
|
|
1455
|
+
mcpTokenPlaceholder: "Bearer Token",
|
|
1456
|
+
mcpTokenSaved: "Token 已保存",
|
|
1457
|
+
mcpAuthOAuth: "OAuth",
|
|
1458
|
+
mcpConnect: "连接",
|
|
1459
|
+
mcpReconnect: "重新连接",
|
|
1460
|
+
mcpConnected: "已连接",
|
|
1461
|
+
mcpNeedsReauth: "需要重连",
|
|
1462
|
+
mcpError: "连接错误",
|
|
1463
|
+
mcpTools: "个工具",
|
|
1464
|
+
mcpToolPolicy: "工具权限",
|
|
1465
|
+
mcpPolicyApproveAll: "每次调用都询问",
|
|
1466
|
+
mcpPolicyReadOnly: "读取放行,写入询问",
|
|
1467
|
+
mcpPolicyAllowAll: "全部信任(不询问)",
|
|
1468
|
+
mcpNav: "MCP 连接器",
|
|
1469
|
+
mcpAddServer: "添加连接器",
|
|
1470
|
+
mcpCancel: "取消",
|
|
1471
|
+
mcpAuthLabel: "认证方式",
|
|
1472
|
+
mcpServerInfo: "服务器",
|
|
1473
|
+
mcpConnecting: "连接中…",
|
|
1474
|
+
mcpPopupBlocked: "弹窗被浏览器拦截,请允许此站点的弹窗后重试。",
|
|
1475
|
+
mcpConnectionFailed: "连接失败,请检查 URL 和认证方式是否正确。",
|
|
1476
|
+
mcpRefresh: "刷新",
|
|
1477
|
+
mcpProbing: "刷新中…",
|
|
1478
|
+
mcpToolsLabel: "工具",
|
|
1479
|
+
mcpRead: "读取",
|
|
1480
|
+
mcpWrite: "写入"
|
|
594
1481
|
};
|
|
595
1482
|
//#endregion
|
|
596
1483
|
//#region ../../../packages/client/ui-edge/src/client/index.ts
|
|
@@ -619,11 +1506,22 @@ window.__ModuleLoader__.load({
|
|
|
619
1506
|
globalThis.location.assign(path);
|
|
620
1507
|
}
|
|
621
1508
|
});
|
|
622
|
-
const
|
|
1509
|
+
const edgeInjected = () => ({
|
|
623
1510
|
hooks: { edgeSettings: controller.store },
|
|
624
1511
|
load: () => controller.load(),
|
|
625
1512
|
copyUpgrade: () => controller.copyUpgrade(),
|
|
626
|
-
signOut: () => controller.signOut()
|
|
1513
|
+
signOut: () => controller.signOut(),
|
|
1514
|
+
setApprovalMode: (mode) => controller.setApprovalMode(mode)
|
|
1515
|
+
});
|
|
1516
|
+
const mcpInjected = () => ({
|
|
1517
|
+
hooks: { edgeSettings: controller.store },
|
|
1518
|
+
load: () => controller.load(),
|
|
1519
|
+
saveMcpServers: (servers) => controller.saveMcpServers(servers),
|
|
1520
|
+
saveMcpToken: (name, token) => controller.saveMcpToken(name, token),
|
|
1521
|
+
setMcpToolPolicy: (name, mode) => controller.setMcpToolPolicy(name, mode),
|
|
1522
|
+
probeMcpServer: (name) => controller.probeMcpServer(name),
|
|
1523
|
+
getMcpTools: (name) => controller.getMcpTools(name),
|
|
1524
|
+
startOAuthConnect: (name, url) => controller.startOAuthConnect(name, url)
|
|
627
1525
|
});
|
|
628
1526
|
slots.inject("settings.section", () => slots.register({
|
|
629
1527
|
name: "settings.section",
|
|
@@ -631,8 +1529,16 @@ window.__ModuleLoader__.load({
|
|
|
631
1529
|
order: 90,
|
|
632
1530
|
label: () => ctx.locale.bind("settings.edge")("nav"),
|
|
633
1531
|
locale: "settings.edge",
|
|
634
|
-
inject:
|
|
1532
|
+
inject: edgeInjected
|
|
635
1533
|
}, EdgeSettingsSection));
|
|
1534
|
+
slots.inject("settings.section", () => slots.register({
|
|
1535
|
+
name: "settings.section",
|
|
1536
|
+
id: "mcp-connectors",
|
|
1537
|
+
order: 55,
|
|
1538
|
+
label: () => ctx.locale.bind("settings.edge")("mcpNav"),
|
|
1539
|
+
locale: "settings.edge",
|
|
1540
|
+
inject: mcpInjected
|
|
1541
|
+
}, EdgeMcpSection));
|
|
636
1542
|
ctx.inject(["remote.session"], (scope) => {
|
|
637
1543
|
scope.effect(() => {
|
|
638
1544
|
const session = scope.get("remote.session");
|