dsh-agent-plugins-market 0.10.0 → 0.11.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/client/client.js +223 -131
- package/client/client.js.map +1 -1
- package/lib/packages/market-bundle/src/application/catalog.js +8 -0
- package/lib/packages/market-bundle/src/index.js +4 -4
- package/lib/packages/market-bundle/src/platform/settings-namespace.js +4 -16
- package/lib/packages/market-bundle/src/platform/settings-schema.js +6 -6
- package/lib/packages/market-bundle/src/routes.js +14 -0
- package/lib/packages/market-contracts/src/contracts/market.js +1 -0
- package/lib/packages/market-contracts/src/contracts/settings.js +20 -43
- package/lib/packages/market-contracts/src/ports/ports.js +1 -0
- package/lib/packages/market-mcp/src/application/mcp/mcp-direct-config.js +28 -0
- package/lib/packages/market-mcp/src/application/mcp/mcp-status.js +36 -8
- package/lib/packages/market-mcp/src/application/mcp-service.js +44 -3
- package/lib/packages/market-runtime/src/runtime/core/reconciler.js +12 -0
- package/lib/types/packages/market-bundle/src/application/catalog.d.ts +6 -0
- package/lib/types/packages/market-bundle/src/index.d.ts +1 -1
- package/lib/types/packages/market-bundle/src/platform/settings-namespace.d.ts +4 -18
- package/lib/types/packages/market-bundle/src/platform/settings-schema.d.ts +6 -6
- package/lib/types/packages/market-contracts/src/contracts/market.d.ts +1 -0
- package/lib/types/packages/market-contracts/src/contracts/mcp-status.d.ts +16 -0
- package/lib/types/packages/market-contracts/src/contracts/settings.d.ts +15 -39
- package/lib/types/packages/market-contracts/src/ports/ports.d.ts +11 -0
- package/lib/types/packages/market-contracts/src/ports/queries.d.ts +2 -0
- package/lib/types/packages/market-mcp/src/application/mcp/mcp-direct-config.d.ts +12 -0
- package/lib/types/packages/market-mcp/src/application/mcp/mcp-status.d.ts +8 -2
- package/lib/types/packages/market-mcp/src/application/mcp-service.d.ts +12 -0
- package/lib/types/packages/market-runtime/src/runtime/core/reconciler.d.ts +13 -0
- package/package.json +1 -1
package/client/client.js
CHANGED
|
@@ -851,11 +851,10 @@ function ActiveOverlay$1({ target, t, visible, slow }) {
|
|
|
851
851
|
* resolved values off the settings snapshot it is handed. Changing a default is
|
|
852
852
|
* therefore a one-line edit in this module.
|
|
853
853
|
*
|
|
854
|
-
*
|
|
855
|
-
*
|
|
856
|
-
*
|
|
857
|
-
*
|
|
858
|
-
* selects the language of displayed translations, including English.
|
|
854
|
+
* Every default is a plain boolean or word, so this module alone answers a
|
|
855
|
+
* section that says nothing. {@link resolveTranslationTarget} still selects the
|
|
856
|
+
* language translations are written in; that choice is independent of whether
|
|
857
|
+
* translations are displayed.
|
|
859
858
|
*
|
|
860
859
|
* @module contracts/settings
|
|
861
860
|
*/
|
|
@@ -867,14 +866,11 @@ const MARKET_SETTINGS_NAMESPACE = "dsh-agent-plugins-market";
|
|
|
867
866
|
* These are user-visible behavior: a flip here is a behavior change that ships
|
|
868
867
|
* with its documentation, not a private implementation detail.
|
|
869
868
|
*
|
|
870
|
-
* `translationEnabled` is the one
|
|
871
|
-
*
|
|
872
|
-
*
|
|
873
|
-
* answers
|
|
874
|
-
*
|
|
875
|
-
* the field at all, an absence that is load-bearing: a schema default would
|
|
876
|
-
* reach the live config reference and erase the difference between "the user
|
|
877
|
-
* never set this" and "the user turned it off".
|
|
869
|
+
* `translationEnabled` is the one field the namespace schema declares no
|
|
870
|
+
* default for. The field stays absent until the user writes it, which is what
|
|
871
|
+
* lets the card tell "never set" from an explicit value, and this constant
|
|
872
|
+
* answers the absent case. A schema default would reach the live config
|
|
873
|
+
* reference and erase that difference.
|
|
878
874
|
*/
|
|
879
875
|
const MARKET_SETTINGS_DEFAULTS = {
|
|
880
876
|
mcpEnhanced: true,
|
|
@@ -882,8 +878,8 @@ const MARKET_SETTINGS_DEFAULTS = {
|
|
|
882
878
|
downloadRegion: "auto",
|
|
883
879
|
feedbackEnabled: true,
|
|
884
880
|
autoUpdateSources: false,
|
|
885
|
-
translationEnabled:
|
|
886
|
-
agentPresetsEnabled:
|
|
881
|
+
translationEnabled: true,
|
|
882
|
+
agentPresetsEnabled: true
|
|
887
883
|
};
|
|
888
884
|
/**
|
|
889
885
|
* Narrow an untrusted stored region to a setting; anything else reads as the
|
|
@@ -899,22 +895,6 @@ function narrowBoolean(value, fallback) {
|
|
|
899
895
|
return typeof value === "boolean" ? value : fallback;
|
|
900
896
|
}
|
|
901
897
|
/**
|
|
902
|
-
* Whether one interface language renders the market's Chinese dictionary.
|
|
903
|
-
*
|
|
904
|
-
* This is the host's own rule rather than a second reading of it:
|
|
905
|
-
* `bindHostLocale` (`runtime/host/host-locale.ts`) answers every preference
|
|
906
|
-
* that is not English with the Chinese dictionary, so as far as the interface is
|
|
907
|
-
* concerned everything that is not English is Chinese — an absent preference
|
|
908
|
-
* included, which the host reads as zh.
|
|
909
|
-
*
|
|
910
|
-
* This determines only the default display preference: Chinese starts on and
|
|
911
|
-
* English starts off. It must not gate an explicitly enabled translation.
|
|
912
|
-
* @param localePreference - the host `locale.preference`, or undefined while nothing supplies one.
|
|
913
|
-
*/
|
|
914
|
-
function interfaceLanguageTranslates(localePreference) {
|
|
915
|
-
return localePreference === void 0 || !localePreference.toLowerCase().startsWith("en");
|
|
916
|
-
}
|
|
917
|
-
/**
|
|
918
898
|
* Resolve a stored settings section the way the host resolves it: each field
|
|
919
899
|
* takes its stored value when it is one this field accepts, and its default
|
|
920
900
|
* otherwise.
|
|
@@ -925,14 +905,12 @@ function interfaceLanguageTranslates(localePreference) {
|
|
|
925
905
|
* function is what keeps a second reading of "what does missing mean" from
|
|
926
906
|
* growing somewhere else.
|
|
927
907
|
*
|
|
928
|
-
* A stored
|
|
929
|
-
*
|
|
930
|
-
*
|
|
931
|
-
* a user who never set the field and leave every other user alone.
|
|
908
|
+
* A stored value always wins: the user's own answer is never overridden by a
|
|
909
|
+
* default. Only a section that says nothing about the field takes the value in
|
|
910
|
+
* {@link MARKET_SETTINGS_DEFAULTS}.
|
|
932
911
|
* @param section - the stored (or absent) namespace section, untrusted.
|
|
933
|
-
* @param localePreference - the host `locale.preference` the language-derived default follows.
|
|
934
912
|
*/
|
|
935
|
-
function resolveMarketSettings(section
|
|
913
|
+
function resolveMarketSettings(section) {
|
|
936
914
|
const stored = typeof section === "object" && section !== null ? section : {};
|
|
937
915
|
return {
|
|
938
916
|
mcpEnhanced: narrowBoolean(stored["mcpEnhanced"], MARKET_SETTINGS_DEFAULTS.mcpEnhanced),
|
|
@@ -940,7 +918,7 @@ function resolveMarketSettings(section, localePreference) {
|
|
|
940
918
|
downloadRegion: narrowDownloadRegion(stored["downloadRegion"]),
|
|
941
919
|
feedbackEnabled: narrowBoolean(stored["feedbackEnabled"], MARKET_SETTINGS_DEFAULTS.feedbackEnabled),
|
|
942
920
|
autoUpdateSources: narrowBoolean(stored["autoUpdateSources"], MARKET_SETTINGS_DEFAULTS.autoUpdateSources),
|
|
943
|
-
translationEnabled: narrowBoolean(stored["translationEnabled"],
|
|
921
|
+
translationEnabled: narrowBoolean(stored["translationEnabled"], MARKET_SETTINGS_DEFAULTS.translationEnabled),
|
|
944
922
|
agentPresetsEnabled: narrowBoolean(stored["agentPresetsEnabled"], MARKET_SETTINGS_DEFAULTS.agentPresetsEnabled)
|
|
945
923
|
};
|
|
946
924
|
}
|
|
@@ -973,6 +951,7 @@ const MARKET_ROUTES = {
|
|
|
973
951
|
setSurfaceToggle: `${MARKET_API_PREFIX}surface-toggles/set`,
|
|
974
952
|
mcpStatus: `${MARKET_API_PREFIX}mcp-status`,
|
|
975
953
|
addMcpServer: `${MARKET_API_PREFIX}mcp-servers/add`,
|
|
954
|
+
removeMcpServer: `${MARKET_API_PREFIX}mcp-servers/remove`,
|
|
976
955
|
lspStatus: `${MARKET_API_PREFIX}lsp-status`,
|
|
977
956
|
lspServers: `${MARKET_API_PREFIX}lsp-servers`,
|
|
978
957
|
addLspServer: `${MARKET_API_PREFIX}lsp-servers/add`,
|
|
@@ -1510,6 +1489,23 @@ async function addMcpServer(name, config, policy) {
|
|
|
1510
1489
|
});
|
|
1511
1490
|
});
|
|
1512
1491
|
}
|
|
1492
|
+
/**
|
|
1493
|
+
* Remove one user-owned MCP server from its declaration file.
|
|
1494
|
+
*
|
|
1495
|
+
* A suite-declared server belongs to its source, so the backend refuses it;
|
|
1496
|
+
* only the `@user-mcp` declaration is the user's to delete.
|
|
1497
|
+
*
|
|
1498
|
+
* @param suiteId - the source-qualified suite id the status row carries.
|
|
1499
|
+
* @param serverKey - the server key inside that suite's declaration.
|
|
1500
|
+
*/
|
|
1501
|
+
async function removeMcpServer(suiteId, serverKey) {
|
|
1502
|
+
return withBusyOperation(async () => {
|
|
1503
|
+
await postAction("mcp-servers/remove", {
|
|
1504
|
+
suiteId,
|
|
1505
|
+
serverKey
|
|
1506
|
+
});
|
|
1507
|
+
});
|
|
1508
|
+
}
|
|
1513
1509
|
/** Drop one server's OAuth grant so its next mount re-runs browser authorization. */
|
|
1514
1510
|
async function reauthorizeMcpServer(serverName) {
|
|
1515
1511
|
return withBusyOperation(async () => {
|
|
@@ -2061,6 +2057,10 @@ const zh = {
|
|
|
2061
2057
|
mcpRetryPreservesCredentials: "重新尝试连接失败的托管服务;保留已有凭据。此操作会检查所有托管 MCP 服务。",
|
|
2062
2058
|
mcpReauthExplain: "这将清除本服务已保存的 OAuth 授权并重新连接,可能中断正在使用它的请求。仅在需要更换账号或授权权限时使用;若服务要求登录,请在打开的浏览器页面完成授权。",
|
|
2063
2059
|
mcpConfirmReauth: "清除授权并重新连接",
|
|
2060
|
+
mcpDelete: "删除连接器",
|
|
2061
|
+
mcpDeleteTitle: "删除连接器「{name}」",
|
|
2062
|
+
mcpDeleteDesc: "该连接器的用户声明将被移除,此操作不可撤销。",
|
|
2063
|
+
mcpDeleteConfirm: "确认删除",
|
|
2064
2064
|
mcpOauthDefault: "授权默认开启",
|
|
2065
2065
|
mcpSaveFirst: "请先保存配置,再执行连接操作;连接操作只使用已保存的配置。",
|
|
2066
2066
|
mcpStillUnavailable: "操作已执行,但服务仍未连接成功。",
|
|
@@ -2208,6 +2208,7 @@ const zh = {
|
|
|
2208
2208
|
failureGuideUnmount: "卸载没有完成:宿主里可能还留着旧进程,重启宿主后再试。",
|
|
2209
2209
|
failureGuideOrphanedTools: "声明它的套件已停用或卸载,工具却仍在注册表中:重启宿主即可清除。",
|
|
2210
2210
|
failureGuideDisabledOverride: "已在配置覆写中停用这个服务。",
|
|
2211
|
+
failureGuidePresetDemand: "该服务由当前会话的预设选中,因此保持挂载;预设生效期间面板开关无法卸载它。",
|
|
2211
2212
|
failureGuideModifiedOverride: "配置覆写改动了这个服务,实际运行的不是套件声明的原始配置。",
|
|
2212
2213
|
panelAdd: "新增",
|
|
2213
2214
|
panelEdit: "编辑",
|
|
@@ -2246,11 +2247,9 @@ const zh = {
|
|
|
2246
2247
|
autoUpdateDesc: "每 6 小时刷新全部已配置来源。",
|
|
2247
2248
|
feedbackToggleDesc: "Agent 遇到本插件的问题时可自动提交 issue 反馈。",
|
|
2248
2249
|
translationToggleLabel: "自动翻译",
|
|
2249
|
-
|
|
2250
|
-
translationToggleDesc: "按界面语言显示描述与文档译文,名称保持原文。中文默认开启、英文默认关闭,手动选择优先。文档展开时按需翻译,支持原文、译文和双语对照;结果缓存在本地。",
|
|
2250
|
+
translationToggleDesc: "按界面语言显示描述与文档译文,名称保持原文。默认开启,手动选择优先。文档展开时按需翻译,支持原文、译文和双语对照;结果缓存在本地。",
|
|
2251
2251
|
agentPresetsToggleLabel: "Agent 预设管理",
|
|
2252
|
-
|
|
2253
|
-
agentPresetsToggleDesc: "在会话输入框“权限”右侧显示 Agent 预设管理入口:按会话启用预设的能力集合。默认关闭。",
|
|
2252
|
+
agentPresetsToggleDesc: "在会话输入框“权限”右侧显示 Agent 预设管理入口:按会话启用预设的能力集合。默认开启。",
|
|
2254
2253
|
translationShowOriginal: "显示原文",
|
|
2255
2254
|
translationShowTranslated: "显示译文",
|
|
2256
2255
|
translationViewLabel: "文档阅读模式",
|
|
@@ -2524,6 +2523,10 @@ const en = {
|
|
|
2524
2523
|
mcpRetryPreservesCredentials: "Retries failed managed connections without clearing credentials. Checks all managed MCP services.",
|
|
2525
2524
|
mcpReauthExplain: "This clears the saved OAuth grant for this service and reconnects it, which may interrupt active requests. Use it to change accounts or permissions. If sign-in is required, complete authorization in the browser page that opens.",
|
|
2526
2525
|
mcpConfirmReauth: "Clear authorization and reconnect",
|
|
2526
|
+
mcpDelete: "Delete connector",
|
|
2527
|
+
mcpDeleteTitle: "Delete connector “{name}”",
|
|
2528
|
+
mcpDeleteDesc: "This removes the connector from the user MCP declaration. This cannot be undone.",
|
|
2529
|
+
mcpDeleteConfirm: "Delete",
|
|
2527
2530
|
mcpOauthDefault: "OAuth on by default",
|
|
2528
2531
|
mcpSaveFirst: "Save configuration before connection actions; they use saved configuration only.",
|
|
2529
2532
|
mcpStillUnavailable: "The operation finished, but the service is still not connected.",
|
|
@@ -2671,6 +2674,7 @@ const en = {
|
|
|
2671
2674
|
failureGuideUnmount: "Unmounting did not finish: the host may still hold the old process; restart the host and try again.",
|
|
2672
2675
|
failureGuideOrphanedTools: "The suite that declared it is off or uninstalled, but its tools are still registered: restart the host to clear them.",
|
|
2673
2676
|
failureGuideDisabledOverride: "This service is switched off in the configuration override.",
|
|
2677
|
+
failureGuidePresetDemand: "The active session preset selects this service, so it stays mounted; the panel switch cannot unmount it while that preset is active.",
|
|
2674
2678
|
failureGuideModifiedOverride: "A configuration override changed this service; what runs is not the suite’s own declaration.",
|
|
2675
2679
|
panelAdd: "Add",
|
|
2676
2680
|
panelEdit: "Edit",
|
|
@@ -2709,11 +2713,9 @@ const en = {
|
|
|
2709
2713
|
autoUpdateDesc: "Refreshes every configured source every 6 hours.",
|
|
2710
2714
|
feedbackToggleDesc: "The agent may auto-file an issue when it hits a problem in this plugin.",
|
|
2711
2715
|
translationToggleLabel: "Auto-translate",
|
|
2712
|
-
|
|
2713
|
-
translationToggleDesc: "Shows descriptions and documents in the interface language; names stay as authored. On by default in Chinese and off in English, unless you choose otherwise. Documents translate on expansion with original, translation and bilingual views. Results are cached locally.",
|
|
2716
|
+
translationToggleDesc: "Shows descriptions and documents in the interface language; names stay as authored. On by default unless you choose otherwise. Documents translate on expansion with original, translation and bilingual views. Results are cached locally.",
|
|
2714
2717
|
agentPresetsToggleLabel: "Agent preset manager",
|
|
2715
|
-
|
|
2716
|
-
agentPresetsToggleDesc: "Shows the Agent preset manager entry beside Permissions in the composer: enable a preset per session. Off by default.",
|
|
2718
|
+
agentPresetsToggleDesc: "Shows the Agent preset manager entry beside Permissions in the composer: enable a preset per session. On by default.",
|
|
2717
2719
|
translationShowOriginal: "Show original text",
|
|
2718
2720
|
translationShowTranslated: "Show translated text",
|
|
2719
2721
|
translationViewLabel: "Document reading mode",
|
|
@@ -3483,67 +3485,42 @@ function hasHan(text) {
|
|
|
3483
3485
|
/**
|
|
3484
3486
|
* Read-only translation preference shared by panels and menu integrations.
|
|
3485
3487
|
* The host form owns persistence; this projection carries the resolved boolean
|
|
3486
|
-
* — the user's stored value while they have one, the
|
|
3487
|
-
*
|
|
3488
|
-
*
|
|
3489
|
-
*
|
|
3488
|
+
* — the user's stored value while they have one, the plugin default otherwise
|
|
3489
|
+
* — across late binding and namespace replacement. The switch is on by default
|
|
3490
|
+
* in every interface language; target-language selection does not override an
|
|
3491
|
+
* explicit on or off.
|
|
3490
3492
|
* @module client/ui/translation-enabled
|
|
3491
3493
|
*/
|
|
3492
|
-
/** The settings entry the harness locale plugin owns; the node half names the same entry. */
|
|
3493
|
-
const LOCALE_SETTINGS_ENTRY = "locale";
|
|
3494
|
-
/**
|
|
3495
|
-
* Read the interface language off the locale plugin's settings form.
|
|
3496
|
-
*
|
|
3497
|
-
* An absent preference reads as zh — the rule every host-facing read gives it
|
|
3498
|
-
* (`runtime/host/host-locale.ts`), so the derived default cannot disagree with
|
|
3499
|
-
* the language the market renders its own copy in.
|
|
3500
|
-
* @param form - the host form for the `locale` entry.
|
|
3501
|
-
* @returns the language source the derived default follows.
|
|
3502
|
-
*/
|
|
3503
|
-
function bindInterfaceLanguage(form) {
|
|
3504
|
-
return {
|
|
3505
|
-
current: () => {
|
|
3506
|
-
const preference = form.getSnapshot().value?.preference;
|
|
3507
|
-
return typeof preference === "string" ? preference : "zh";
|
|
3508
|
-
},
|
|
3509
|
-
subscribe: (listener) => form.subscribe(listener)
|
|
3510
|
-
};
|
|
3511
|
-
}
|
|
3512
3494
|
const state$2 = (0, _deepseek_ai_dsh_client_store.createSnapshotStore)(MARKET_SETTINGS_DEFAULTS.translationEnabled);
|
|
3513
3495
|
let binding$1;
|
|
3514
3496
|
let unsubscribeSource$1;
|
|
3515
|
-
let unsubscribeLanguage;
|
|
3516
3497
|
/** Shared read and subscription API. Consumers cannot write the preference. */
|
|
3517
3498
|
const translationEnabled = {
|
|
3518
3499
|
getSnapshot: () => state$2.getSnapshot(),
|
|
3519
3500
|
subscribe: (listener) => state$2.subscribe(listener)
|
|
3520
3501
|
};
|
|
3521
3502
|
/**
|
|
3522
|
-
* Whether translation is on for one stored section
|
|
3523
|
-
*
|
|
3503
|
+
* Whether translation is on for one stored section: the user's stored boolean,
|
|
3504
|
+
* else the plugin default the contract declares.
|
|
3524
3505
|
* @param section - the host form's accepted section.
|
|
3525
|
-
* @param language - the host interface language; absent keeps the declared default.
|
|
3526
3506
|
*/
|
|
3527
|
-
function effectiveTranslationEnabled(section
|
|
3528
|
-
return resolveMarketSettings(section
|
|
3507
|
+
function effectiveTranslationEnabled(section) {
|
|
3508
|
+
return resolveMarketSettings(section).translationEnabled;
|
|
3529
3509
|
}
|
|
3530
3510
|
/**
|
|
3531
|
-
* Follow the host form
|
|
3532
|
-
*
|
|
3533
|
-
* consumers.
|
|
3511
|
+
* Follow the host form without adding persistence or polling. Replacing a
|
|
3512
|
+
* binding disconnects its source, not the existing consumers.
|
|
3534
3513
|
*
|
|
3535
3514
|
* A form that has not answered yet keeps the pre-answer default rather than
|
|
3536
|
-
* resolving the absent section: the
|
|
3537
|
-
*
|
|
3538
|
-
*
|
|
3539
|
-
* defined value is resolved through the contract.
|
|
3515
|
+
* resolving the absent section: the declared default describes a section the
|
|
3516
|
+
* host has answered and deliberately left open, and reading an absent section
|
|
3517
|
+
* as one the document left open would report a state the document may not be
|
|
3518
|
+
* in. Only a defined value is resolved through the contract.
|
|
3540
3519
|
* @param next - the host form for this plugin's settings namespace.
|
|
3541
|
-
* @param language - the interface language the derived default follows; absent keeps the declared default.
|
|
3542
3520
|
* @returns an idempotent disposer; an older disposer cannot clear a newer binding.
|
|
3543
3521
|
*/
|
|
3544
|
-
function bindTranslationEnabled(next
|
|
3522
|
+
function bindTranslationEnabled(next) {
|
|
3545
3523
|
unsubscribeSource$1?.();
|
|
3546
|
-
unsubscribeLanguage?.();
|
|
3547
3524
|
const current = {};
|
|
3548
3525
|
binding$1 = current;
|
|
3549
3526
|
const sync = () => {
|
|
@@ -3553,18 +3530,15 @@ function bindTranslationEnabled(next, language) {
|
|
|
3553
3530
|
state$2.set(MARKET_SETTINGS_DEFAULTS.translationEnabled);
|
|
3554
3531
|
return;
|
|
3555
3532
|
}
|
|
3556
|
-
state$2.set(effectiveTranslationEnabled(answered
|
|
3533
|
+
state$2.set(effectiveTranslationEnabled(answered));
|
|
3557
3534
|
};
|
|
3558
3535
|
unsubscribeSource$1 = next.subscribe(sync);
|
|
3559
|
-
unsubscribeLanguage = language?.subscribe(sync);
|
|
3560
3536
|
sync();
|
|
3561
3537
|
return () => {
|
|
3562
3538
|
if (binding$1 !== current) return;
|
|
3563
3539
|
binding$1 = void 0;
|
|
3564
3540
|
unsubscribeSource$1?.();
|
|
3565
|
-
unsubscribeLanguage?.();
|
|
3566
3541
|
unsubscribeSource$1 = void 0;
|
|
3567
|
-
unsubscribeLanguage = void 0;
|
|
3568
3542
|
state$2.set(MARKET_SETTINGS_DEFAULTS.translationEnabled);
|
|
3569
3543
|
};
|
|
3570
3544
|
}
|
|
@@ -37695,6 +37669,7 @@ const FAILURE_GUIDANCE_LABEL = {
|
|
|
37695
37669
|
unmount: "failureGuideUnmount",
|
|
37696
37670
|
orphanedTools: "failureGuideOrphanedTools",
|
|
37697
37671
|
disabledOverride: "failureGuideDisabledOverride",
|
|
37672
|
+
presetDemand: "failureGuidePresetDemand",
|
|
37698
37673
|
modifiedOverride: "failureGuideModifiedOverride",
|
|
37699
37674
|
foreignMount: "mcpForeignHint",
|
|
37700
37675
|
duplicateMount: "mcpDuplicateHint"
|
|
@@ -37711,6 +37686,7 @@ function failureGuidanceKey(diagnostic) {
|
|
|
37711
37686
|
if (code === "duplicate-mount") return "duplicateMount";
|
|
37712
37687
|
if (code === "orphaned-tools") return "orphanedTools";
|
|
37713
37688
|
if (code === "disabled-override") return "disabledOverride";
|
|
37689
|
+
if (code === "preset-demand") return "presetDemand";
|
|
37714
37690
|
if (code === "modified-override") return "modifiedOverride";
|
|
37715
37691
|
const text = [diagnostic.reason, ...diagnostic.causes ?? []].filter((line) => line !== void 0).join("\n");
|
|
37716
37692
|
if (/does not support dynamic plugin mounting/i.test(text)) return "hostUnsupported";
|
|
@@ -38464,6 +38440,49 @@ function parseServerDocument(text, key) {
|
|
|
38464
38440
|
};
|
|
38465
38441
|
}
|
|
38466
38442
|
/**
|
|
38443
|
+
* Read one document while a service is being created.
|
|
38444
|
+
*
|
|
38445
|
+
* Creating a service has no declaration key yet, so the pasted document decides
|
|
38446
|
+
* it: a keyed document names its own service and its key is adopted, while a
|
|
38447
|
+
* bare definition — the server object itself, no `mcpServers` seat — is read
|
|
38448
|
+
* under the draft key the name field carries. The strict reader above refuses
|
|
38449
|
+
* any document whose key differs from the declared one, which would trap the
|
|
38450
|
+
* create flow: the pasted key could never become the key of the new service.
|
|
38451
|
+
* The policy half is read the same way in both shapes.
|
|
38452
|
+
*
|
|
38453
|
+
* @param text - the document as the editor holds it.
|
|
38454
|
+
* @param draftKey - the key the name field currently carries, used by a bare definition.
|
|
38455
|
+
* @returns the service's key, definition, and policy.
|
|
38456
|
+
*/
|
|
38457
|
+
function readDraftServerDocument(text, draftKey) {
|
|
38458
|
+
const parsed = JSON.parse(text);
|
|
38459
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("Configuration must be a JSON object");
|
|
38460
|
+
const record = parsed;
|
|
38461
|
+
const policies = asRecord(asRecord(record[HARNESS_NAMESPACE])?.["mcpServers"]);
|
|
38462
|
+
if (!("mcpServers" in record)) {
|
|
38463
|
+
const config = { ...record };
|
|
38464
|
+
if (policies !== void 0) delete config[HARNESS_NAMESPACE];
|
|
38465
|
+
return {
|
|
38466
|
+
key: draftKey,
|
|
38467
|
+
keyed: false,
|
|
38468
|
+
config,
|
|
38469
|
+
policy: asRecord(policies?.[draftKey]) ?? {}
|
|
38470
|
+
};
|
|
38471
|
+
}
|
|
38472
|
+
const servers = asRecord(record["mcpServers"]);
|
|
38473
|
+
const keys = servers === void 0 ? [] : Object.keys(servers);
|
|
38474
|
+
const key = keys[0];
|
|
38475
|
+
if (key === void 0 || keys.length !== 1) throw new Error("mcpServers must name exactly one service while a service is being created");
|
|
38476
|
+
const config = asRecord(servers?.[key]);
|
|
38477
|
+
if (config === void 0) throw new Error(`mcpServers must name a JSON object for the service key "${key}"`);
|
|
38478
|
+
return {
|
|
38479
|
+
key,
|
|
38480
|
+
keyed: true,
|
|
38481
|
+
config,
|
|
38482
|
+
policy: asRecord(policies?.[key]) ?? {}
|
|
38483
|
+
};
|
|
38484
|
+
}
|
|
38485
|
+
/**
|
|
38467
38486
|
* Write the document back in the shape the specification seats it in. Without a
|
|
38468
38487
|
* declaration key the definition is the whole document: wrapping it under an
|
|
38469
38488
|
* empty `mcpServers` key would store a nested document as the service.
|
|
@@ -38526,7 +38545,7 @@ function ServerConfigEditor(props) {
|
|
|
38526
38545
|
let parseError;
|
|
38527
38546
|
try {
|
|
38528
38547
|
if (props.kind === "mcp") {
|
|
38529
|
-
const document = parseServerDocument(props.text, props.serverKey ?? "");
|
|
38548
|
+
const document = props.create === true ? readDraftServerDocument(props.text, props.serverKey ?? "") : parseServerDocument(props.text, props.serverKey ?? "");
|
|
38530
38549
|
parsed = document.config;
|
|
38531
38550
|
policy = document.policy;
|
|
38532
38551
|
} else parsed = parseServerConfig(props.text);
|
|
@@ -38915,6 +38934,13 @@ function ServerConfigDetail({ kind, id, create = false, t, credentials, onSaved,
|
|
|
38915
38934
|
(0, react.useEffect)(() => {
|
|
38916
38935
|
onDirtyChange?.(dirty);
|
|
38917
38936
|
}, [dirty, onDirtyChange]);
|
|
38937
|
+
/**
|
|
38938
|
+
* Read the document in the mode this editor is in. Creating adopts the key
|
|
38939
|
+
* the document names — the document is the source of truth there — while
|
|
38940
|
+
* editing keeps the declared key, because a renamed seat would silently
|
|
38941
|
+
* point the save at a different service.
|
|
38942
|
+
*/
|
|
38943
|
+
const readDocument = (source) => create && kind === "mcp" ? readDraftServerDocument(source, serverKey) : parseServerDocument(source, serverKey);
|
|
38918
38944
|
/** The document's policy half, as the string drafts the timeout fields edit. */
|
|
38919
38945
|
const policyDraft = () => {
|
|
38920
38946
|
if (kind !== "mcp" || text === void 0) return {
|
|
@@ -38922,7 +38948,7 @@ function ServerConfigDetail({ kind, id, create = false, t, credentials, onSaved,
|
|
|
38922
38948
|
startupTimeoutMs: ""
|
|
38923
38949
|
};
|
|
38924
38950
|
try {
|
|
38925
|
-
return policyDraftOfDocument(
|
|
38951
|
+
return policyDraftOfDocument(readDocument(text).policy);
|
|
38926
38952
|
} catch {
|
|
38927
38953
|
return {
|
|
38928
38954
|
toolCallTimeoutMs: "",
|
|
@@ -38930,15 +38956,35 @@ function ServerConfigDetail({ kind, id, create = false, t, credentials, onSaved,
|
|
|
38930
38956
|
};
|
|
38931
38957
|
}
|
|
38932
38958
|
};
|
|
38933
|
-
/**
|
|
38959
|
+
/**
|
|
38960
|
+
* Write the timeout drafts back into the document's policy half. The rewrite
|
|
38961
|
+
* composes under the current key and keeps the definition as read, so a bare
|
|
38962
|
+
* definition becomes keyed here rather than losing the policy seat.
|
|
38963
|
+
*/
|
|
38934
38964
|
const updatePolicy = (draft) => {
|
|
38935
38965
|
if (text === void 0) return;
|
|
38936
38966
|
try {
|
|
38937
|
-
const document =
|
|
38967
|
+
const document = readDocument(text);
|
|
38938
38968
|
setText(composeServerDocument(serverKey, document.config, policyDocumentOfDraft(document.policy, draft)));
|
|
38939
38969
|
} catch {}
|
|
38940
38970
|
};
|
|
38941
38971
|
/**
|
|
38972
|
+
* Take the document the editor just produced. While creating a service the
|
|
38973
|
+
* document names its own key: a pasted keyed document decides the name, so
|
|
38974
|
+
* the name field mirrors it instead of keeping a draft key the document no
|
|
38975
|
+
* longer uses. The document stays exactly as typed.
|
|
38976
|
+
*/
|
|
38977
|
+
const changeText = (next) => {
|
|
38978
|
+
setText(next);
|
|
38979
|
+
if (!(create && kind === "mcp")) return;
|
|
38980
|
+
try {
|
|
38981
|
+
const draft = readDraftServerDocument(next, serverKey);
|
|
38982
|
+
if (!draft.keyed || draft.key === serverKey) return;
|
|
38983
|
+
setServerKey(draft.key);
|
|
38984
|
+
setName(draft.key);
|
|
38985
|
+
} catch {}
|
|
38986
|
+
};
|
|
38987
|
+
/**
|
|
38942
38988
|
* Read the service again and rebuild every derived value from the response.
|
|
38943
38989
|
* `silent` keeps the editor mounted for the read-back that follows a save, so
|
|
38944
38990
|
* the user stays in the section they were editing. A service being created has
|
|
@@ -38989,7 +39035,7 @@ function ServerConfigDetail({ kind, id, create = false, t, credentials, onSaved,
|
|
|
38989
39035
|
setFieldErrors(void 0);
|
|
38990
39036
|
try {
|
|
38991
39037
|
if (kind === "mcp") {
|
|
38992
|
-
const document =
|
|
39038
|
+
const document = readDocument(text ?? "");
|
|
38993
39039
|
if (create) {
|
|
38994
39040
|
const policy = policyRequestOfDocuments({}, document.policy);
|
|
38995
39041
|
if (Object.keys(policy).length === 0) await addMcpServer(name.trim(), document.config);
|
|
@@ -39011,17 +39057,14 @@ function ServerConfigDetail({ kind, id, create = false, t, credentials, onSaved,
|
|
|
39011
39057
|
};
|
|
39012
39058
|
const saveable = valid && (create ? name.trim() !== "" : dirty);
|
|
39013
39059
|
const nameCopy = NAME_COPY[kind];
|
|
39014
|
-
let nameEditable = true;
|
|
39015
|
-
if (create && kind === "mcp") try {
|
|
39016
|
-
parseServerDocument(text ?? "", serverKey);
|
|
39017
|
-
} catch {
|
|
39018
|
-
nameEditable = false;
|
|
39019
|
-
}
|
|
39020
39060
|
const changeName = (next) => {
|
|
39021
|
-
|
|
39022
|
-
|
|
39023
|
-
|
|
39024
|
-
|
|
39061
|
+
const key = next.trim();
|
|
39062
|
+
if (kind === "mcp" && key !== "" && text !== void 0) {
|
|
39063
|
+
setServerKey(key);
|
|
39064
|
+
try {
|
|
39065
|
+
const document = readDraftServerDocument(text, key);
|
|
39066
|
+
if (document.keyed) setText(composeServerDocument(key, document.config, document.policy));
|
|
39067
|
+
} catch {}
|
|
39025
39068
|
}
|
|
39026
39069
|
setName(next);
|
|
39027
39070
|
};
|
|
@@ -39033,6 +39076,7 @@ function ServerConfigDetail({ kind, id, create = false, t, credentials, onSaved,
|
|
|
39033
39076
|
text,
|
|
39034
39077
|
t,
|
|
39035
39078
|
serverKey,
|
|
39079
|
+
create,
|
|
39036
39080
|
disabled: busy || !editable,
|
|
39037
39081
|
onValidityChange: setValid,
|
|
39038
39082
|
...credentials === void 0 ? {} : { credentials },
|
|
@@ -39043,7 +39087,7 @@ function ServerConfigDetail({ kind, id, create = false, t, credentials, onSaved,
|
|
|
39043
39087
|
placeholder: t(nameCopy.placeholder),
|
|
39044
39088
|
"aria-label": t(nameCopy.label),
|
|
39045
39089
|
readOnly: !create,
|
|
39046
|
-
disabled: busy
|
|
39090
|
+
disabled: busy,
|
|
39047
39091
|
onChange: (event) => {
|
|
39048
39092
|
if (create) changeName(event.target.value);
|
|
39049
39093
|
}
|
|
@@ -39054,7 +39098,7 @@ function ServerConfigDetail({ kind, id, create = false, t, credentials, onSaved,
|
|
|
39054
39098
|
onPolicyDraftChange: updatePolicy,
|
|
39055
39099
|
...backend === void 0 ? {} : { backend },
|
|
39056
39100
|
...fieldErrors === void 0 ? {} : { fieldErrors },
|
|
39057
|
-
onChange:
|
|
39101
|
+
onChange: changeText
|
|
39058
39102
|
}), loading || error && text === void 0 ? null : editable ? (0, react.createElement)(DetailFooterAction, { children: (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
39059
39103
|
variant: "primary",
|
|
39060
39104
|
disabled: busy || !saveable,
|
|
@@ -39140,6 +39184,7 @@ function McpStatusPanel({ t, credentials }) {
|
|
|
39140
39184
|
const [view, setView] = useWorkspaceView();
|
|
39141
39185
|
const [selected, setSelected] = (0, react.useState)(void 0);
|
|
39142
39186
|
const [editing, setEditing] = (0, react.useState)();
|
|
39187
|
+
const [confirmDelete, setConfirmDelete] = (0, react.useState)();
|
|
39143
39188
|
const [adding, setAdding] = (0, react.useState)(false);
|
|
39144
39189
|
const [showOriginal, setShowOriginal] = (0, react.useState)(false);
|
|
39145
39190
|
const flipOriginal = () => setShowOriginal((current) => !current);
|
|
@@ -39198,6 +39243,35 @@ function McpStatusPanel({ t, credentials }) {
|
|
|
39198
39243
|
});
|
|
39199
39244
|
};
|
|
39200
39245
|
useTranslationRefresh(t, refresh);
|
|
39246
|
+
/**
|
|
39247
|
+
* Delete one user-owned server. A suite-declared server belongs to its
|
|
39248
|
+
* source, so the backend refuses it and the card offers no such action; the
|
|
39249
|
+
* row disappears from the re-read list because its declaration is gone.
|
|
39250
|
+
* The failure is reported in the panel rather than thrown, so the shared
|
|
39251
|
+
* confirmation closes the same way whether or not the request succeeded.
|
|
39252
|
+
*/
|
|
39253
|
+
const remove = async (entry) => {
|
|
39254
|
+
const suiteId = entry.suiteId;
|
|
39255
|
+
const serverKey = entry.serverKey;
|
|
39256
|
+
if (suiteId === void 0 || serverKey === void 0) return;
|
|
39257
|
+
setError(void 0);
|
|
39258
|
+
try {
|
|
39259
|
+
await removeMcpServer(suiteId, serverKey);
|
|
39260
|
+
setPayload(await fetchMcpStatus());
|
|
39261
|
+
setSelected((current) => current?.id === entry.id ? void 0 : current);
|
|
39262
|
+
} catch (caught) {
|
|
39263
|
+
setError(clientErrorMessage(t, caught));
|
|
39264
|
+
}
|
|
39265
|
+
};
|
|
39266
|
+
/** Deleting is irreversible, so the card asks through the shared confirmation. */
|
|
39267
|
+
const askDelete = (entry) => {
|
|
39268
|
+
const name = mcpDisplayName(entry);
|
|
39269
|
+
setConfirmDelete({
|
|
39270
|
+
title: t("mcpDeleteTitle", { name }),
|
|
39271
|
+
description: t("mcpDeleteDesc", { name }),
|
|
39272
|
+
onConfirm: () => remove(entry)
|
|
39273
|
+
});
|
|
39274
|
+
};
|
|
39201
39275
|
const toggle = (entry) => {
|
|
39202
39276
|
const suiteId = entry.suiteId;
|
|
39203
39277
|
const serverKey = entry.serverKey;
|
|
@@ -39278,7 +39352,8 @@ function McpStatusPanel({ t, credentials }) {
|
|
|
39278
39352
|
t,
|
|
39279
39353
|
onClick: () => setSelected(entry),
|
|
39280
39354
|
onToggle: () => toggle(entry),
|
|
39281
|
-
onEdit: () => setEditing(entry)
|
|
39355
|
+
onEdit: () => setEditing(entry),
|
|
39356
|
+
...deletable(entry) ? { onDelete: () => askDelete(entry) } : {}
|
|
39282
39357
|
}))), adding ? (0, react.createElement)(McpAddModal, {
|
|
39283
39358
|
t,
|
|
39284
39359
|
credentials,
|
|
@@ -39305,9 +39380,22 @@ function McpStatusPanel({ t, credentials }) {
|
|
|
39305
39380
|
credentials,
|
|
39306
39381
|
onClose: () => setEditing(void 0),
|
|
39307
39382
|
onSaved: refresh
|
|
39383
|
+
}), (0, react.createElement)(ConfirmModal, {
|
|
39384
|
+
state: confirmDelete,
|
|
39385
|
+
confirmLabel: t("mcpDeleteConfirm"),
|
|
39386
|
+
cancelLabel: t("cancel"),
|
|
39387
|
+
onClose: () => setConfirmDelete(void 0)
|
|
39308
39388
|
}));
|
|
39309
39389
|
}
|
|
39310
39390
|
/**
|
|
39391
|
+
* Whether this row is the user's own declaration. A suite declares its servers
|
|
39392
|
+
* in its own `mcp.json`, and an observed mount has no declaration here at all,
|
|
39393
|
+
* so only a user-owned direct server is this panel's to delete.
|
|
39394
|
+
*/
|
|
39395
|
+
function deletable(entry) {
|
|
39396
|
+
return entry.kind === "direct" && entry.suiteId !== void 0 && entry.serverKey !== void 0;
|
|
39397
|
+
}
|
|
39398
|
+
/**
|
|
39311
39399
|
* One inventory card: the server name with its state tag on the identity row
|
|
39312
39400
|
* and the enable switch on its trailing edge; the endpoint on the body row;
|
|
39313
39401
|
* tool count and transport on the source row. The reason text, the state
|
|
@@ -39315,7 +39403,7 @@ function McpStatusPanel({ t, credentials }) {
|
|
|
39315
39403
|
* configuration) live in the detail dialog, so a wall of failing cards stays
|
|
39316
39404
|
* scannable.
|
|
39317
39405
|
*/
|
|
39318
|
-
function McpCard({ entry, t, onClick, onToggle, onEdit }) {
|
|
39406
|
+
function McpCard({ entry, t, onClick, onToggle, onEdit, onDelete }) {
|
|
39319
39407
|
const interactive = interactiveCardProps(onClick);
|
|
39320
39408
|
const toolCount = entry.tools.length === 1 ? t("mcpTool") : t("mcpTools");
|
|
39321
39409
|
const switchable = entry.suiteId !== void 0 && entry.serverKey !== void 0 && entry.state !== "foreign";
|
|
@@ -39340,7 +39428,16 @@ function McpCard({ entry, t, onClick, onToggle, onEdit }) {
|
|
|
39340
39428
|
event.stopPropagation();
|
|
39341
39429
|
onEdit();
|
|
39342
39430
|
}
|
|
39343
|
-
}, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconEditOutlineMedium)) : null, (0, react.createElement)("
|
|
39431
|
+
}, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconEditOutlineMedium)) : null, onDelete === void 0 ? null : (0, react.createElement)("button", {
|
|
39432
|
+
type: "button",
|
|
39433
|
+
className: `${resource_card_module_default.iconBtn} ${resource_card_module_default.iconBtnDanger}`,
|
|
39434
|
+
title: t("mcpDelete"),
|
|
39435
|
+
"aria-label": `${t("mcpDelete")} ${displayName}`,
|
|
39436
|
+
onClick: (event) => {
|
|
39437
|
+
event.stopPropagation();
|
|
39438
|
+
onDelete();
|
|
39439
|
+
}
|
|
39440
|
+
}, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconTrashOutlineMedium)), (0, react.createElement)("span", {
|
|
39344
39441
|
className: resource_card_module_default.switchWrap,
|
|
39345
39442
|
onClick: (event) => event.stopPropagation()
|
|
39346
39443
|
}, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Switch, {
|
|
@@ -41068,10 +41165,9 @@ function settingsRegionField(field) {
|
|
|
41068
41165
|
* renderer face for the card.
|
|
41069
41166
|
* @param scope - the host configuration form for the market namespace.
|
|
41070
41167
|
* @param probeSource - reads the live host-client and region state from the market API.
|
|
41071
|
-
* @param language - the interface language the translation row's derived default follows; absent keeps the declared default.
|
|
41072
41168
|
* @returns the model, the injected face, and the disposer releasing the form.
|
|
41073
41169
|
*/
|
|
41074
|
-
function bindMarketCardForm(scope, probeSource
|
|
41170
|
+
function bindMarketCardForm(scope, probeSource) {
|
|
41075
41171
|
const model = new _deepseek_ai_dsh_client_ui_primitives.SettingsFormModel(scope, [
|
|
41076
41172
|
settingsBooleanField("mcpEnhanced"),
|
|
41077
41173
|
settingsBooleanField("scanProjectLayouts"),
|
|
@@ -41103,16 +41199,18 @@ function bindMarketCardForm(scope, probeSource, language) {
|
|
|
41103
41199
|
let probeGeneration = 0;
|
|
41104
41200
|
const hostClientMissing = () => probe !== void 0 && !probe.hostClient.available;
|
|
41105
41201
|
const compatBlocked = () => model.field("mcpEnhanced").text !== "true" && (probeStatus === "loading" || hostClientMissing());
|
|
41106
|
-
/**
|
|
41202
|
+
/**
|
|
41203
|
+
* Resolve the stored or staged display preference through the contract, so a
|
|
41204
|
+
* field the document says nothing about reads the plugin default instead of
|
|
41205
|
+
* an empty draft. A staged edit answers for itself from the moment it lands.
|
|
41206
|
+
*/
|
|
41107
41207
|
const translationField = () => {
|
|
41108
41208
|
const field = model.field("translationEnabled");
|
|
41109
41209
|
if (field.invalid) return field;
|
|
41110
41210
|
const section = field.text === "" ? scope.getSnapshot().value : { translationEnabled: field.text === "true" };
|
|
41111
|
-
const current = language?.current();
|
|
41112
|
-
const enabled = effectiveTranslationEnabled(section, current);
|
|
41113
41211
|
return {
|
|
41114
41212
|
...field,
|
|
41115
|
-
text: String(
|
|
41213
|
+
text: String(effectiveTranslationEnabled(section))
|
|
41116
41214
|
};
|
|
41117
41215
|
};
|
|
41118
41216
|
const project = () => {
|
|
@@ -41132,9 +41230,6 @@ function bindMarketCardForm(scope, probeSource, language) {
|
|
|
41132
41230
|
};
|
|
41133
41231
|
};
|
|
41134
41232
|
const store = model.bind(project);
|
|
41135
|
-
const unsubscribeLanguage = language?.subscribe(() => {
|
|
41136
|
-
store.set(project());
|
|
41137
|
-
});
|
|
41138
41233
|
/** Read the host-client probe once; a second call while one is in flight is a no-op. */
|
|
41139
41234
|
const loadProbe = async () => {
|
|
41140
41235
|
if (probeStatus === "loading") return;
|
|
@@ -41162,7 +41257,6 @@ function bindMarketCardForm(scope, probeSource, language) {
|
|
|
41162
41257
|
},
|
|
41163
41258
|
dispose: () => {
|
|
41164
41259
|
probeGeneration += 1;
|
|
41165
|
-
unsubscribeLanguage?.();
|
|
41166
41260
|
model.dispose();
|
|
41167
41261
|
}
|
|
41168
41262
|
};
|
|
@@ -41215,9 +41309,9 @@ function OverrideBadge(props) {
|
|
|
41215
41309
|
onClick: props.onReset
|
|
41216
41310
|
}, props.t("settingReset")));
|
|
41217
41311
|
}
|
|
41218
|
-
/** The head of one field row: its label
|
|
41312
|
+
/** The head of one field row: its label and the override state. */
|
|
41219
41313
|
function FieldHead(props) {
|
|
41220
|
-
return (0, react.createElement)("div", { className: market_module_default.pluginFieldHead }, (0, react.createElement)("div", { className: market_module_default.pluginCardRowLabel }, props.label), props.
|
|
41314
|
+
return (0, react.createElement)("div", { className: market_module_default.pluginFieldHead }, (0, react.createElement)("div", { className: market_module_default.pluginCardRowLabel }, props.label), props.overridden ? props.badge : null);
|
|
41221
41315
|
}
|
|
41222
41316
|
/**
|
|
41223
41317
|
* The reset control: the host's text button, named for what it clears. It
|
|
@@ -41258,7 +41352,6 @@ function SwitchRow(props) {
|
|
|
41258
41352
|
return (0, react.createElement)("div", { className: market_module_default.pluginCardRow }, (0, react.createElement)("div", { className: market_module_default.pluginCardText }, (0, react.createElement)(FieldHead, {
|
|
41259
41353
|
label,
|
|
41260
41354
|
overridden: props.state.overridden,
|
|
41261
|
-
...props.field === "translationEnabled" ? { tag: (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Tag, { tone: "neutral" }, props.t("translationToggleExperimental")) } : props.field === "agentPresetsEnabled" ? { tag: (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Tag, { tone: "neutral" }, props.t("agentPresetsToggleExperimental")) } : {},
|
|
41262
41355
|
badge: (0, react.createElement)(OverrideBadge, {
|
|
41263
41356
|
t: props.t,
|
|
41264
41357
|
disabled: props.disabled,
|
|
@@ -41354,8 +41447,8 @@ function McpPluginCard(props) {
|
|
|
41354
41447
|
/**
|
|
41355
41448
|
* Read-only agent-preset-manager preference shared by the composer slot. The
|
|
41356
41449
|
* host form owns persistence; this projection carries the resolved boolean —
|
|
41357
|
-
* the
|
|
41358
|
-
*
|
|
41450
|
+
* the entry shows by default and a stored false hides it, and a flip shows or
|
|
41451
|
+
* hides the entry without a reload.
|
|
41359
41452
|
* @module client/ui/agent-presets-enabled
|
|
41360
41453
|
*/
|
|
41361
41454
|
const state = (0, _deepseek_ai_dsh_client_store.createSnapshotStore)(MARKET_SETTINGS_DEFAULTS.agentPresetsEnabled);
|
|
@@ -41368,7 +41461,7 @@ const agentPresetsEnabled = {
|
|
|
41368
41461
|
};
|
|
41369
41462
|
/**
|
|
41370
41463
|
* Follow the host form without adding persistence or polling. A form that has
|
|
41371
|
-
* not answered yet keeps the pre-answer default (
|
|
41464
|
+
* not answered yet keeps the pre-answer default (on) rather than resolving
|
|
41372
41465
|
* the absent section: only a defined value is resolved through the contract.
|
|
41373
41466
|
* @param next - the host form for this plugin's settings namespace.
|
|
41374
41467
|
* @returns an idempotent disposer; an older disposer cannot clear a newer binding.
|
|
@@ -42998,8 +43091,8 @@ const REQUIRED_PRIMITIVES = [
|
|
|
42998
43091
|
/** Published composer seat after Permissions; blank and ongoing sessions share one icon entry. */
|
|
42999
43092
|
const COMPOSER_TOGGLE_SLOT = "conversation.input.left";
|
|
43000
43093
|
/**
|
|
43001
|
-
* The slot's payload, behind the
|
|
43002
|
-
*
|
|
43094
|
+
* The slot's payload, behind the preset switch: nothing renders while the
|
|
43095
|
+
* setting is off, and a flip shows the entry without a reload.
|
|
43003
43096
|
*/
|
|
43004
43097
|
function PresetEntrySlot(props) {
|
|
43005
43098
|
if (!useAgentPresetsEnabled() || !props.sessionId) return null;
|
|
@@ -43131,12 +43224,11 @@ function apply(ctx) {
|
|
|
43131
43224
|
if (service === void 0) return;
|
|
43132
43225
|
let card;
|
|
43133
43226
|
const form = service.get(NS);
|
|
43134
|
-
const
|
|
43135
|
-
const unbindTranslation = bindTranslationEnabled(form, language);
|
|
43227
|
+
const unbindTranslation = bindTranslationEnabled(form);
|
|
43136
43228
|
const unbindPresets = bindAgentPresetsEnabled(form);
|
|
43137
43229
|
const stopServed = service.whileServed([NS], () => {
|
|
43138
43230
|
if (slots === void 0) return () => {};
|
|
43139
|
-
const bound = bindMarketCardForm(form, fetchMcpBackend
|
|
43231
|
+
const bound = bindMarketCardForm(form, fetchMcpBackend);
|
|
43140
43232
|
card = bound.face;
|
|
43141
43233
|
const dispose = slots.register({
|
|
43142
43234
|
name: "plugins.bundle.config",
|