@sunshaobei/dsh-mcp-manager 0.0.0-stage → 0.4.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.
Files changed (144) hide show
  1. package/LICENSE +1 -0
  2. package/README.en.md +476 -0
  3. package/README.md +379 -2
  4. package/cordis.patch.yml +9 -0
  5. package/lib/THIRD-PARTY-LICENSES +43 -0
  6. package/lib/client/core/api.d.ts +42 -0
  7. package/lib/client/core/constants.d.ts +58 -0
  8. package/lib/client/core/current-session.d.ts +39 -0
  9. package/lib/client/core/dom.d.ts +19 -0
  10. package/lib/client/core/i18n.d.ts +12 -0
  11. package/lib/client/core/session.d.ts +27 -0
  12. package/lib/client/core/state.d.ts +120 -0
  13. package/lib/client/float/float.d.ts +126 -0
  14. package/lib/client/float/panel.d.ts +29 -0
  15. package/lib/client/float/quick-add.d.ts +38 -0
  16. package/lib/client/float/servers.d.ts +54 -0
  17. package/lib/client/index.d.ts +26 -0
  18. package/lib/client/locales.d.ts +123 -0
  19. package/lib/client/settings/settings-card.d.ts +47 -0
  20. package/lib/client.js +2568 -0
  21. package/lib/index.d.ts +86 -0
  22. package/lib/index.js +10035 -0
  23. package/lib/server/api/deps.d.ts +36 -0
  24. package/lib/server/api/impl/health/type.d.ts +12 -0
  25. package/lib/server/api/impl/service/index.d.ts +28 -0
  26. package/lib/server/api/interface.d.ts +27 -0
  27. package/lib/server/api/routes-controllers.d.ts +61 -0
  28. package/lib/server/api/routes-helpers.d.ts +8 -0
  29. package/lib/server/api/routes.d.ts +58 -0
  30. package/lib/server/catalog/deps.d.ts +51 -0
  31. package/lib/server/catalog/impl/cache-view/index.d.ts +48 -0
  32. package/lib/server/catalog/impl/digest/index.d.ts +19 -0
  33. package/lib/server/catalog/impl/directory/index.d.ts +168 -0
  34. package/lib/server/catalog/impl/entries/index.d.ts +129 -0
  35. package/lib/server/catalog/impl/entries/type.d.ts +19 -0
  36. package/lib/server/catalog/impl/history/index.d.ts +36 -0
  37. package/lib/server/catalog/impl/injection/index.d.ts +45 -0
  38. package/lib/server/catalog/impl/search/type.d.ts +59 -0
  39. package/lib/server/catalog/impl/service/index.d.ts +25 -0
  40. package/lib/server/catalog/interface.d.ts +45 -0
  41. package/lib/server/catalog/search.d.ts +108 -0
  42. package/lib/server/config/config-schema.d.ts +85 -0
  43. package/lib/server/config/impl/env/index.d.ts +24 -0
  44. package/lib/server/config/impl/env/policy.d.ts +54 -0
  45. package/lib/server/config/impl/model/type.d.ts +39 -0
  46. package/lib/server/config/impl/ui/type.d.ts +20 -0
  47. package/lib/server/config/import.d.ts +20 -0
  48. package/lib/server/config/interface.d.ts +15 -0
  49. package/lib/server/config/normalize.d.ts +24 -0
  50. package/lib/server/config/sources-sync.d.ts +32 -0
  51. package/lib/server/config/sources.d.ts +50 -0
  52. package/lib/server/connection/interface.d.ts +86 -0
  53. package/lib/server/connection/orchestrator/deps.d.ts +93 -0
  54. package/lib/server/connection/orchestrator/impl/service/index.d.ts +27 -0
  55. package/lib/server/connection/orchestrator/interface.d.ts +25 -0
  56. package/lib/server/connection/orchestrator/manager.d.ts +484 -0
  57. package/lib/server/connection/orchestrator/tool-names.d.ts +14 -0
  58. package/lib/server/connection/runtime/deps.d.ts +141 -0
  59. package/lib/server/connection/runtime/impl/middleware/type.d.ts +45 -0
  60. package/lib/server/connection/runtime/impl/service/index.d.ts +28 -0
  61. package/lib/server/connection/runtime/interface.d.ts +29 -0
  62. package/lib/server/connection/runtime/limits.d.ts +19 -0
  63. package/lib/server/connection/runtime/middleware.d.ts +194 -0
  64. package/lib/server/erasure/impl/guard/index.d.ts +35 -0
  65. package/lib/server/erasure/interface.d.ts +31 -0
  66. package/lib/server/inject/deps.d.ts +54 -0
  67. package/lib/server/inject/impl/call-timeout/index.d.ts +1 -0
  68. package/lib/server/inject/impl/image-admission/index.d.ts +81 -0
  69. package/lib/server/inject/impl/service/index.d.ts +25 -0
  70. package/lib/server/inject/interface.d.ts +27 -0
  71. package/lib/server/inject/middleware-register.d.ts +114 -0
  72. package/lib/server/pipeline/deps.d.ts +27 -0
  73. package/lib/server/pipeline/impl/args/index.d.ts +26 -0
  74. package/lib/server/pipeline/impl/authorize/index.d.ts +43 -0
  75. package/lib/server/pipeline/impl/msg/index.d.ts +8 -0
  76. package/lib/server/pipeline/impl/project/index.d.ts +43 -0
  77. package/lib/server/pipeline/impl/redact/index.d.ts +13 -0
  78. package/lib/server/pipeline/impl/service/index.d.ts +25 -0
  79. package/lib/server/pipeline/impl/timeout/index.d.ts +8 -0
  80. package/lib/server/pipeline/interface.d.ts +32 -0
  81. package/lib/server/servers/dispatch/deps.d.ts +100 -0
  82. package/lib/server/servers/dispatch/impl/call/index.d.ts +49 -0
  83. package/lib/server/servers/dispatch/impl/redact/index.d.ts +13 -0
  84. package/lib/server/servers/dispatch/interface.d.ts +18 -0
  85. package/lib/server/servers/lifecycle/deps.d.ts +62 -0
  86. package/lib/server/servers/lifecycle/impl/ledger/index.d.ts +52 -0
  87. package/lib/server/servers/lifecycle/impl/logs/index.d.ts +48 -0
  88. package/lib/server/servers/lifecycle/impl/mount/index.d.ts +83 -0
  89. package/lib/server/servers/lifecycle/impl/service/index.d.ts +26 -0
  90. package/lib/server/servers/lifecycle/impl/state/index.d.ts +35 -0
  91. package/lib/server/servers/lifecycle/impl/timeout/index.d.ts +39 -0
  92. package/lib/server/servers/lifecycle/interface.d.ts +56 -0
  93. package/lib/server/shared/compose.d.ts +38 -0
  94. package/lib/server/shared/constants.d.ts +62 -0
  95. package/lib/server/shared/file-io.d.ts +8 -0
  96. package/lib/server/shared/host-faces.d.ts +206 -0
  97. package/lib/server/shared/interface.d.ts +14 -0
  98. package/lib/server/shared/paths.d.ts +66 -0
  99. package/lib/server/shared/tool-names.d.ts +11 -0
  100. package/lib/server/stats/impl/collector.d.ts +68 -0
  101. package/lib/server/stats/impl/type.d.ts +41 -0
  102. package/lib/server/stats/interface.d.ts +13 -0
  103. package/lib/server/store/impl/middleware-state.d.ts +45 -0
  104. package/lib/server/store/impl/store.d.ts +43 -0
  105. package/lib/server/store/interface.d.ts +9 -0
  106. package/lib/server/upgrade/deps.d.ts +25 -0
  107. package/lib/server/upgrade/impl/chain/index.d.ts +2 -0
  108. package/lib/server/upgrade/impl/service/index.d.ts +9 -0
  109. package/lib/server/upgrade/impl/steps/index.d.ts +19 -0
  110. package/lib/server/upgrade/impl/steps/project-layout.d.ts +24 -0
  111. package/lib/server/upgrade/impl/steps/storage-layout.d.ts +17 -0
  112. package/lib/server/upgrade/impl/version/index.d.ts +7 -0
  113. package/lib/server/upgrade/interface.d.ts +21 -0
  114. package/lib/server/visibility/impl/mask/index.d.ts +7 -0
  115. package/lib/server/visibility/interface.d.ts +46 -0
  116. package/lib/server/workspace/impl/full-name/index.d.ts +24 -0
  117. package/lib/server/workspace/impl/root-resolution/index.d.ts +18 -0
  118. package/lib/server/workspace/impl/scope/index.d.ts +14 -0
  119. package/lib/server/workspace/impl/server-id/index.d.ts +17 -0
  120. package/lib/server/workspace/interface.d.ts +22 -0
  121. package/lib/shared/constants.d.ts +22 -0
  122. package/lib/shared/dto.d.ts +62 -0
  123. package/lib/shared/frames.d.ts +19 -0
  124. package/lib/shared/interface.d.ts +22 -0
  125. package/lib/shared/placement-math.d.ts +81 -0
  126. package/lib/shared/routes.d.ts +43 -0
  127. package/lib/shared/service.d.ts +85 -0
  128. package/lib/shared/status.d.ts +23 -0
  129. package/lib/vendor/shared/README.md +147 -0
  130. package/lib/vendor/shared/client/ensure-style.d.ts +23 -0
  131. package/lib/vendor/shared/client/i18n.d.ts +30 -0
  132. package/lib/vendor/shared/client/ui/index.d.ts +214 -0
  133. package/lib/vendor/shared/dsh-home.d.ts +26 -0
  134. package/lib/vendor/shared/host-utils.d.ts +82 -0
  135. package/lib/vendor/shared/loopback.d.ts +12 -0
  136. package/lib/vendor/shared/package.json +12 -0
  137. package/lib/vendor/shared/paths.d.ts +35 -0
  138. package/lib/vendor/shared/settings-namespace.d.ts +82 -0
  139. package/lib/vendor/shared/sse-hub.d.ts +75 -0
  140. package/lib/vendor/shared/upgrade-chain.d.ts +140 -0
  141. package/lib/vendor/shared/upgrade-tick.d.ts +17 -0
  142. package/locale/en.json +6 -0
  143. package/locale/zh.json +6 -0
  144. package/package.json +171 -4
@@ -0,0 +1,120 @@
1
+ /**
2
+ * dsh-mcp-manager — 客户端状态类型与工厂。
3
+ *
4
+ * 所有可变状态收进单一 McpState 对象,在 apply() 内创建,经参数传递到各模块。
5
+ * 禁止模块级全局变量,确保连续挂载/卸载无残留。
6
+ *
7
+ * 跨端 DTO 形状(服务器列表条目 / 浮窗 UI 配置)的物理定义在 src/shared/dto.ts
8
+ * (D5):这里只做薄 re-export,客户端不得自带等值副本——一致性锁
9
+ * test/e2e/cross-end-lock.test.ts 与 test/integration/service-contract.test.ts 盯这条。
10
+ */
11
+ import { API } from "./constants.js";
12
+ import type { ClientUiConfig, McpServerListEntry, ServerState } from "../../shared/interface.js";
13
+ import type { ISessions } from "@deepseek-ai/dsh-api-session-controller/client";
14
+ import type { LocaleRuntime } from "@deepseek-ai/dsh-client-locale/client";
15
+ import type { SlotRegistry } from "@deepseek-ai/dsh-client-ui-renderer/client";
16
+ export type { ClientUiConfig, McpServerListEntry } from "../../shared/interface.js";
17
+ /** 各状态计数(六态键的物理定义在 shared/status.ts,宿主与客户端同一份)。 */
18
+ export type McpCounts = Partial<Record<ServerState, number>>;
19
+ /** MCP 管理器客户端全部可变状态。 */
20
+ export interface McpState {
21
+ /** 模态面板遮罩层根元素。 */
22
+ overlay: HTMLElement | undefined;
23
+ /** 模态面板卡片根元素。 */
24
+ card: HTMLElement | undefined;
25
+ /** 模态面板 body 容器。 */
26
+ bodyEl: HTMLElement | undefined;
27
+ /** 模态面板是否打开。 */
28
+ open: boolean;
29
+ /** 打开面板时的焦点归属(R6 关还焦:close 时恢复;非元素/已卸载则跳过)。 */
30
+ panelOpener: HTMLElement | undefined;
31
+ /** 当前激活的 tab(servers / quick)。 */
32
+ activeTab: string;
33
+ /** 服务器列表。 */
34
+ servers: McpServerListEntry[];
35
+ /** 各状态计数。 */
36
+ counts: McpCounts;
37
+ /** 正在编辑的服务器名称(undefined 表示新建)。 */
38
+ editingName: string | undefined;
39
+ /** 正在编辑的服务器原始数据。 */
40
+ editing: McpServerListEntry | undefined;
41
+ floatPill: HTMLElement | undefined;
42
+ floatPanel: HTMLElement | undefined;
43
+ floatOpen: boolean;
44
+ currentCwd: string | undefined;
45
+ /**
46
+ * 是否已解析出当前会话(#1028)。false = **未知**,与「已知但无 cwd」是两态:
47
+ * 未知时不得向宿主上报 `cwd:""`,否则会把「读不到」变成「清空项目级绑定」。
48
+ */
49
+ sessionResolved: boolean;
50
+ /** 未知态的一次性告警闸(可观测性:未知态无 UI 表现,不告警等于静默失效)。 */
51
+ warnedUnknownSession: boolean;
52
+ /**
53
+ * 连续未知帧计数(#1028 告警口径)。官方会话快照要等 mainView 持有才就绪,
54
+ * 故**首帧未知是竞态不是故障**(每次冷启动必现);用它把噪声与真失联分开。
55
+ */
56
+ unknownSessionFrames: number;
57
+ projectRoot: string | undefined;
58
+ updateFloatState: (() => void) | undefined;
59
+ mcpUiConfig: ClientUiConfig;
60
+ API: typeof API;
61
+ }
62
+ /** 创建初始状态对象。 */
63
+ export declare function createState(): McpState;
64
+ /**
65
+ * 跨模块动作回调集合。
66
+ * index.ts 装配,避免 feature 模块间循环依赖——各模块通过 actions 调用
67
+ * 其他模块的功能(如 servers.ts 调用 actions.refresh / actions.resetForm)。
68
+ */
69
+ export interface UiActions {
70
+ refresh: () => Promise<boolean>;
71
+ resetForm: () => void;
72
+ beginEdit: (server: McpServerListEntry) => void;
73
+ switchTab: (tab: string) => void;
74
+ close: () => void;
75
+ showPanel: () => void;
76
+ toggleFloat: (force?: boolean) => void;
77
+ }
78
+ /**
79
+ * locale 服务最小面:官方 `LocaleRuntime`(dsh-client-locale,宿主 ctx.locale)的 Pick。
80
+ * 成员一律必选——官方类上本就是必选方法,服务本体缺失由 `ctx.get("locale")` 的
81
+ * `| undefined` 表达;index.ts 里既有的 typeof 守卫(H4)是运行时防御,原样保留。
82
+ *
83
+ * 官方形状对齐说明:官方 `register` 两个重载都返回 disposer `() => void`,本包调用点
84
+ * **既成事实地丢弃**该返回值(只把 subscribe 的 unsub 存进 effect 卸载),此处仅把返回
85
+ * 类型按官方补齐,**不新增任何清理/生命周期逻辑**。`getSnapshot` 官方必返 `LocaleSnapshot`,
86
+ * 本包只在 typeof 守卫里探测成员存在,从不读返回值,故面里只带方法类型不带结果。
87
+ */
88
+ export type McpLocaleService = Pick<LocaleRuntime, "register" | "subscribe" | "getSnapshot" | "bind">;
89
+ /**
90
+ * slots 服务最小面:官方 `SlotRegistry`(dsh-client-ui-renderer,宿主 ctx.slots)的
91
+ * inject/register Pick,与 index.ts 的行配置装配面同源同形。
92
+ *
93
+ * 官方形状对齐说明:官方 `inject(key, callback)` 与 `register(options, component)` **都**
94
+ * 返回 disposer `() => void`;本类型此前把 inject 误写成返回 void(index.ts 的局部声明
95
+ * 反而写对了),此处一律以官方为准。成员不再 optional:服务本体缺失已由
96
+ * `ctx.get("slots")` 的 `| undefined` 表达,调用点本就先判空再调(G2 零行为改动)。
97
+ */
98
+ export type McpSlotsService = Pick<SlotRegistry, "inject" | "register">;
99
+ /**
100
+ * 客户端上下文最小面(S2:get 重载 + effect + sessions?;H6 不反向依赖未清洁形状)。
101
+ * get("locale"/"slots")返回上两个官方派生面,未声明服务时为 undefined;其余名回落 unknown。
102
+ */
103
+ export interface McpClientContext {
104
+ get(name: "locale"): McpLocaleService | undefined;
105
+ get(name: "slots"): McpSlotsService | undefined;
106
+ get(name: string): unknown;
107
+ effect: (fn: () => () => void, label?: string) => void;
108
+ /**
109
+ * 官方会话服务(#1028:不再自建镜像面——rc.2 的 `SessionListState` 已无 `current`,
110
+ * 自建形状会与官方静默分叉)。未注入时为 undefined。
111
+ */
112
+ sessions?: ISessions;
113
+ }
114
+ /**
115
+ * 客户端 HTTP 请求选项最小面(P3-b/B6:api 二选一选 A 泛型)。
116
+ * 继承 DOM RequestInit(method/headers/body/signal),仅增 timeoutMs 兜底预算。
117
+ */
118
+ export interface ApiRequestOptions extends RequestInit {
119
+ timeoutMs?: number;
120
+ }
@@ -0,0 +1,126 @@
1
+ /**
2
+ * dsh-mcp-manager — 客户端右上角浮窗。
3
+ *
4
+ * 浮窗胶囊(状态点 + 摘要计数)挂在会话滚动容器右上角,点击展开下拉面板
5
+ * 展示项目/全局 MCP 服务器列表 + 快捷操作(连接/断开/禁用)。
6
+ * 跨模块动作(showPanel / refresh)经 actions 注入,不直接引用 panel 模块。
7
+ */
8
+ import type { McpClientContext, McpServerListEntry, McpState, UiActions } from "../core/state.js";
9
+ import type { ClientUiConfig, FloatBreakpoint, ViewportPoint } from "../../shared/interface.js";
10
+ /** 胶囊状态点配色:失败红 / 有连接绿 / 否则中性灰(与历史三态一致)。 */
11
+ export declare function pillDotColor(fail: boolean, connected: number): string;
12
+ /**
13
+ * 胶囊的 title / aria-label:一台服务器都没有时不设(保留宿主默认 tooltip),
14
+ * 有失败时追加失败计数,否则 aria 给出「已连/总数」(无总数时 title 保持朴素)。
15
+ */
16
+ export declare function pillHints(total: number, bad: number, connected: number): {
17
+ title: string;
18
+ aria: string;
19
+ };
20
+ /** 渲染浮窗胶囊(状态点 + 摘要计数 + 失败/中性态)。 */
21
+ export declare function renderPill(state: McpState): void;
22
+ /**
23
+ * 一行上的动作描述:按钮外观 + 打到哪个口 + 请求形状 + 失败告警的稳定标识。
24
+ * tag 是 console 文案用的动作名(与 i18n 文案解耦:翻界面不改日志)。
25
+ */
26
+ interface RowAction {
27
+ className: string;
28
+ label: string;
29
+ url: string;
30
+ method: "POST" | "PATCH";
31
+ tag: string;
32
+ /** 只有 PATCH 动作带载荷(连接/断开是纯 POST,历史形状如此)。 */
33
+ body?: string;
34
+ }
35
+ /** 主操作(每行恰好一个):connected → 断开;disabled → 启用;其余 → 连接。 */
36
+ export declare function primaryRowAction(server: McpServerListEntry, state: McpState, cwdQuery: string): RowAction;
37
+ /** 禁用动作(仅非 disabled 行有):URL 不带 cwd(历史形状如此,勿补)。 */
38
+ export declare function disableRowAction(server: McpServerListEntry, state: McpState): RowAction;
39
+ /** 请求 init:带载荷的 PATCH 补 content-type;纯 POST 不带头(历史形状)。 */
40
+ export declare function rowRequestInit(action: RowAction): {
41
+ method: string;
42
+ headers?: Record<string, string>;
43
+ body?: string;
44
+ };
45
+ /**
46
+ * 按状态分桶(桶序 = STATUS_ORDER,固定六态先建空桶)。未知状态归 stopped 桶——
47
+ * 六态是唯一合法取值域,落到兜底桶而不是丢弃该行。
48
+ */
49
+ export declare function bucketServersByStatus(list: McpServerListEntry[]): Map<string, McpServerListEntry[]>;
50
+ /** 行级 stagger 序号:动画关闭返回 undefined(该行不加 dm-stagger、不进序)。 */
51
+ export declare function nextStagger(staggerBase: {
52
+ n: number;
53
+ }, animate: boolean): number | undefined;
54
+ /** 浮窗标题的项目名:项目根末段;无项目根回落「全局会话」。 */
55
+ export declare function floatProjectName(state: McpState): string;
56
+ /** 需要置顶提醒的服务器(失败 + 重连中)。 */
57
+ export declare function needsAttention(server: McpServerListEntry): boolean;
58
+ /** 渲染浮窗下拉面板(健康摘要 + 失败优先 + scope 分组)。 */
59
+ export declare function renderFloatPanel(state: McpState, actions: UiActions): void;
60
+ /** 切换浮窗展开/收起(Apple Fluid:锚点→对角 scale;先渲染后定位)。 */
61
+ export declare function toggleFloat(state: McpState, actions: UiActions, force?: boolean): void;
62
+ /** 水平锚点判定:left-* 贴左缘,其余贴右缘(胶囊与面板共用同一口径)。 */
63
+ export declare function anchorsLeft(position: string | undefined): boolean;
64
+ /** Fluid 展开原点:锚点所在的那个角(胶囊贴边角 → 面板向对角展开)。 */
65
+ export declare function transformOriginFor(isLeft: boolean, anchorBottom: boolean): string;
66
+ /** 下拉面板定位(fixed 跟随胶囊,避免被滚动容器裁剪;四角感知 + 视口终 clamp)。 */
67
+ export declare function placePanel(state: McpState): void;
68
+ /** 会话滚动容器:聊天消息实际滚动的区域(shell 的 data-conversation-scroll)。 */
69
+ export declare function conversationHost(): Element;
70
+ /** 全局 overlay 层:下拉面板挂这里(fixed 定位,避免被滚动容器裁剪)。 */
71
+ export declare function panelHost(): Element;
72
+ /**
73
+ * 当前会话是否空白会话(空白会话用另一档垂直偏移)。取不到会话面一律判非空白。
74
+ *
75
+ * #1028:与 core/session.ts 共用 core/current-session.ts 单一接缝,判定改用官方口径
76
+ * `retainedBy.mainView`;`blank` 直读官方 `SessionSummary.blank`,不从 cwd 空串推。
77
+ */
78
+ export declare function isBlankSession(ctx: McpClientContext): boolean;
79
+ /** 从 settings.yaml 读取的配置决定新/老会话垂直偏移。 */
80
+ export declare function floatTopOffset(ctx: McpClientContext, state: McpState): number;
81
+ /** 胶囊位置配置白名单:只认四个锚点,其余(含缺省)回落 top-right(历史行为)。 */
82
+ export declare function floatPositionOf(cfg: ClientUiConfig): ClientUiConfig["position"];
83
+ /** 胶囊定位入参(锚点 + 偏移):位置白名单归一、水平偏移缺省 8、垂直偏移按会话形态。 */
84
+ export declare function pillAnchors(cfg: ClientUiConfig, ctx: McpClientContext, state: McpState): {
85
+ isLeft: boolean;
86
+ isBottom: boolean;
87
+ offsetX: number;
88
+ offsetY: number;
89
+ };
90
+ /** 底部锚点是否改用 composer seat 上缘当下边界(#128:仅非 wide 断点)。 */
91
+ export declare function usesComposerSeat(isBottom: boolean, bp: FloatBreakpoint): boolean;
92
+ /** 底部锚点的容器下边界:composer seat 贴底时改用 seat 上缘(胶囊上移到输入区上方)。 */
93
+ export declare function dockedBottomEdge(containerRect: {
94
+ top: number;
95
+ bottom: number;
96
+ }): number;
97
+ /** 胶囊定位纯计算的入参(DOM 读口在调用面,坐标算式在这里,可直测)。 */
98
+ interface PillPlacementInput {
99
+ rect: {
100
+ top: number;
101
+ bottom: number;
102
+ left: number;
103
+ right: number;
104
+ };
105
+ width: number;
106
+ height: number;
107
+ isLeft: boolean;
108
+ isBottom: boolean;
109
+ offsetX: number;
110
+ offsetY: number;
111
+ /** 底部锚点下边界(已含 composer seat 改写,见 dockedBottomEdge)。 */
112
+ bottomEdge: number;
113
+ viewportW: number;
114
+ viewportH: number;
115
+ }
116
+ /**
117
+ * 胶囊终坐标(纯计算):水平按锚点贴容器左右缘、垂直按锚点(bottom 从下边界上推、
118
+ * clamp 到视口上缘;top 从容器顶下移),最后统一走视口 clamp。
119
+ */
120
+ export declare function pillPlacement(input: PillPlacementInput): ViewportPoint;
121
+ /**
122
+ * 挂载浮窗:胶囊继续挂在会话滚动容器(scrollBody)内并钉住右上角,下拉面板
123
+ * fixed 跟随。返回 disposer 函数。
124
+ */
125
+ export declare function mountFloat(ctx: McpClientContext, state: McpState, actions: UiActions): () => void;
126
+ export {};
@@ -0,0 +1,29 @@
1
+ /**
2
+ * dsh-mcp-manager — 客户端模态面板生命周期。
3
+ *
4
+ * 面板的打开/关闭/tab 切换/数据刷新。
5
+ * 跨模块渲染(renderServers / buildQuickAdd / renderPill / renderFloatPanel)
6
+ * 直接 import 用到的模块——本模块是 feature 模块的汇聚点,构成单向依赖图:
7
+ * panel → servers / quick-add / float。
8
+ */
9
+ import type { McpState, UiActions } from "../core/state.js";
10
+ /**
11
+ * 刷新服务器列表与浮窗摘要(单飞:in-flight 复用;#111 变更点驱动)。
12
+ * 返回 true=成功;false=失败(调用方按退避重试)。
13
+ */
14
+ export declare function refresh(state: McpState, actions: UiActions): Promise<boolean>;
15
+ /** 切换面板 tab(servers / quick)。 */
16
+ export declare function switchTab(state: McpState, actions: UiActions, tab: string): void;
17
+ /** 关闭模态面板(Fluid:卡片中心收束 + 遮罩淡出;完成后再 hidden)。
18
+ *
19
+ * R1 状态同翻:state.open=false 的同一同步块内摘除 aria-modal(不经 300ms
20
+ * 动画回调——动画被打断/定时器漂移时标记与状态永久错位,见 #947)。
21
+ * R2 常驻壳无标记:hidden 元素仍被 querySelector 命中,故必须摘属性而非
22
+ * 置 "false"(裸 [aria-modal] 存在检查仍命中 "false",且关闭态留 "false"
23
+ * 语义错误)。R6 关还焦:同步把焦点还给打开者(便宜且安全)。
24
+ */
25
+ export declare function close(state: McpState): void;
26
+ /** 打开模态面板(首次调用时创建 DOM 结构;Fluid:中心 scale 0.78→1)。 */
27
+ export declare function showPanel(state: McpState, actions: UiActions): void;
28
+ /** C4:卸载配对清理(index.ts effect disposer 调用)——移除 Escape keydown 监听。 */
29
+ export declare function disposePanel(state: McpState): void;
@@ -0,0 +1,38 @@
1
+ /**
2
+ * dsh-mcp-manager — 客户端「快速接入」页:多源 mcp.json 编辑器与保存执行面。
3
+ *
4
+ * 手填表单已整体移除(v0.4.0):添加/编辑一律经「多源 mcp.json 编辑器」
5
+ * (beginEdit 打开 openJsonEditor,保存走 performSaveRequest)。跨模块动作
6
+ * (refresh / switchTab)经 actions 注入,不直接引用 panel 模块,避免循环依赖。
7
+ */
8
+ import type { McpState, UiActions } from "../core/state.js";
9
+ import type { McpManagerServerInput, McpServerListEntry } from "../../shared/interface.js";
10
+ /** 当前保存归属(project/global):按 projectRoot 回落,无 DOM 依赖。 */
11
+ export declare function formScopeValue(state: McpState): string;
12
+ /** 当前会话 cwd(POST body 携带,宿主据此切换项目级 MCP)。 */
13
+ export declare function currentCwdBody(state: McpState): Record<string, string>;
14
+ /** 是否处于编辑态(editingName 已设)。 */
15
+ export declare function isEditing(state: McpState): boolean;
16
+ /** 重置编辑态(表单已移除,只清编辑面)。 */
17
+ export declare function resetForm(state: McpState): void;
18
+ /** 迁移式保存判据:正在编辑,且(改名 或 改归属)。宿主 PATCH 按 (scope,name) 定位且
19
+ * 强制沿用定位名,故这两类改动必须走 POST+DELETE(见 performSaveRequest)。 */
20
+ export declare function isMigratedEdit(state: McpState, server: McpManagerServerInput, payload: Record<string, unknown>): boolean;
21
+ /** JSON 写请求的公共 init(PATCH / POST 共用)。 */
22
+ export declare function jsonWriteInit(payload: Record<string, unknown>): {
23
+ method: "POST" | "PATCH";
24
+ headers: Record<string, string>;
25
+ body: string;
26
+ };
27
+ /**
28
+ * 保存执行面(三种落点)与中止信号。
29
+ * C11 迁移式保存:宿主 PATCH 按 (scope,name) 定位且强制沿用定位名——编辑改名/改归属
30
+ * 会 404 not found 无引导。先 POST 新条目再 DELETE 旧条目,任何失败即抛(保留原条目),
31
+ * 避免半迁移脏数据。
32
+ * @returns false = 已中止(大声失败),调用方不得 refresh。
33
+ */
34
+ export declare function performSaveRequest(state: McpState, server: McpManagerServerInput, payload: Record<string, unknown>): Promise<boolean>;
35
+ /** 进入编辑模式:记录编辑态并弹出大号 JSON 编辑器(行内编辑太小,弃用表单填充)。 */
36
+ export declare function beginEdit(state: McpState, actions: UiActions, server: McpServerListEntry): void;
37
+ /** 构建「快速接入」页面(多源 mcp.json 编辑器)。 */
38
+ export declare function buildQuickAdd(state: McpState, actions: UiActions): HTMLElement;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * dsh-mcp-manager — 客户端「服务器列表页」渲染。
3
+ *
4
+ * 按状态分级展示服务器卡片(端点 / 错误 / 工具列表 / 操作按钮)。
5
+ * 跨模块动作(refresh / resetForm / beginEdit)经 actions 注入,不直接引用
6
+ * panel/quick-add 模块,避免循环依赖。
7
+ */
8
+ import type { McpServerListEntry, McpState, UiActions } from "../core/state.js";
9
+ /** 服务器端点摘要:streamable-http 显示 URL,stdio 显示 command + args。 */
10
+ export declare function endpointOf(server: McpServerListEntry): string;
11
+ /** 操作按钮(统一失败提示)。 */
12
+ export declare function actionButton(label: string, onClick: () => void | Promise<void>, primary?: boolean, danger?: boolean): HTMLElement;
13
+ /** 工具折叠组:interactive 出 checkbox(可逐个禁用),否则出纯文本工具名。 */
14
+ export declare function serverToolsDetails(server: McpServerListEntry, toolCount: number, opts: {
15
+ tools: boolean;
16
+ openTools?: Set<string>;
17
+ }, state: McpState, actions: UiActions, interactive: boolean): HTMLElement;
18
+ /** 一个操作按钮的规格(label / 主按钮样式 / 执行体)。 */
19
+ interface ActionSpec {
20
+ label: string;
21
+ primary: boolean;
22
+ danger?: boolean;
23
+ run: () => void | Promise<void>;
24
+ }
25
+ /** JSON 写请求 init(PATCH enabled 用;形态与 quick-add 同款)。 */
26
+ export declare function jsonPatchInit(enabled: boolean): {
27
+ method: "PATCH";
28
+ headers: Record<string, string>;
29
+ body: string;
30
+ };
31
+ /** POST 后刷新(连接/断开/重连三个动作的执行体同式)。 */
32
+ export declare function postThenRefresh(state: McpState, actions: UiActions, url: string): () => Promise<void>;
33
+ export declare function statusActions(server: McpServerListEntry, state: McpState, actions: UiActions, scopeQuery: string, cwdQuery: string): ActionSpec[];
34
+ /** 禁用动作(非 disabled 行才有):PATCH 后若正在编辑该条目则重置表单。 */
35
+ export declare function disableAction(server: McpServerListEntry, state: McpState, actions: UiActions, scopeQuery: string, cwdQuery: string): ActionSpec;
36
+ /** 删除动作:先确认(未确认即中止),DELETE 后若正在编辑该条目则重置表单。 */
37
+ export declare function deleteAction(server: McpServerListEntry, state: McpState, actions: UiActions, scopeQuery: string): ActionSpec;
38
+ /** 需要置顶提醒的服务器(失败 + 重连中)。 */
39
+ export declare function needsAttention(server: McpServerListEntry): boolean;
40
+ /** 按状态分桶(桶序 = STATUS_ORDER;未知状态归 stopped 桶,不丢行)。 */
41
+ export declare function bucketByStatus(list: McpServerListEntry[]): Map<string, McpServerListEntry[]>;
42
+ /** 卡片根类名:失败 / 重连中加 --fail 修饰。 */
43
+ export declare function serverCardClass(server: McpServerListEntry): string;
44
+ /** 卡片头部:名称 / transport 徽标 / scope 徽标 / 状态徽标 / 工具计数。 */
45
+ export declare function serverCardHeader(server: McpServerListEntry, toolCount: number): HTMLElement;
46
+ /** 渲染单台服务器卡片。 */
47
+ export declare function renderServer(server: McpServerListEntry, state: McpState, actions: UiActions, opts?: {
48
+ tools: boolean;
49
+ openTools?: Set<string>;
50
+ }): HTMLElement;
51
+ /** 渲染服务器列表页(#362 交互拍板 1a:项目级 / 全局级两大分组,各自内部再按状态)。
52
+ * 单池(#767)后两大分组的服务器都经中间层,工具 checkbox 一律可用。 */
53
+ export declare function renderServers(state: McpState, actions: UiActions): void;
54
+ export {};
@@ -0,0 +1,26 @@
1
+ /**
2
+ * dsh-mcp-manager — 浏览器端客户端入口(装配层)。
3
+ *
4
+ * 仅含装配逻辑,不含业务实现。业务实现在 constants/dom/servers/quick-add/
5
+ * panel/float/session/settings-card 各模块中。
6
+ *
7
+ * 挂载浏览器端:注入样式 + 右上角浮窗(会话跟随)+ 管理面板 + 插件行配置页。
8
+ * 失败策略:只 warn 不抛,绝不让 GUI 启动失败。
9
+ *
10
+ * 客户端干净模块:只导出 apply/inject,契约外壳(IIFE/load/Symbol.toStringTag 装配)
11
+ * 由 scripts/build/build-client.ts 统一生成——源码不写任何 loader 痕迹。
12
+ * 样式:独立 style.css(见同目录),build-client 的 .css text-loader 构建期内联为字符串。
13
+ *
14
+ * React 由 dsh web 的 factory require("react") 注入(build-client externals 路径);
15
+ * 插件行配置页由宿主 React 渲染,故客户端必须提供 React 组件。
16
+ */
17
+ import { type McpClientContext } from "./core/state.js";
18
+ import { type McpLocaleKey } from "./locales.js";
19
+ declare module "@deepseek-ai/dsh-client-ui-slots" {
20
+ interface LocaleNamespaceMap {
21
+ /** dsh-mcp-manager 浮窗/面板/表单/设置卡文案。 */
22
+ mcpManager: McpLocaleKey;
23
+ }
24
+ }
25
+ export declare function apply(ctx: McpClientContext): void;
26
+ export declare const inject: string[];
@@ -0,0 +1,123 @@
1
+ /**
2
+ * dsh-mcp-manager — 客户端文案字典(issue #348:复用官方 dsh-client-locale)。
3
+ *
4
+ * 双语平衡:`zh` 为 key 源;`en` 必须覆盖全部 key(编译期锁平衡)。
5
+ * 动态数据用 `{name}` 占位模板,渲染期由 t 插值。
6
+ * 不进字典:console 日志、placeholder 示例值(context7/npx/URL/JSON 样例)、
7
+ * 服务器名等动态数据(官方原则:数据不翻译)。
8
+ */
9
+ /** 简体中文字典(key 源)。 */
10
+ export declare const zh: {
11
+ readonly stConnected: "运行中";
12
+ readonly stConnecting: "连接中";
13
+ readonly stReconnecting: "重连中";
14
+ readonly stStopped: "未连接";
15
+ readonly stDisabled: "已停用";
16
+ readonly stFailed: "失败";
17
+ readonly connect: "连接";
18
+ readonly disconnect: "断开";
19
+ readonly reconnect: "重连";
20
+ readonly enable: "启用";
21
+ readonly enableAndConnect: "启用并连接";
22
+ readonly disable: "禁用";
23
+ readonly edit: "编辑";
24
+ readonly delete: "删除";
25
+ readonly save: "保存";
26
+ readonly cancel: "取消";
27
+ readonly refresh: "刷新";
28
+ readonly close: "关闭";
29
+ readonly cancelEdit: "取消编辑";
30
+ readonly saveFail: "保存失败:{msg}";
31
+ readonly actionFail: "操作失败:{msg}";
32
+ readonly loadFail: "加载失败:{msg}";
33
+ readonly floatAriaLabel: "MCP 管理器";
34
+ readonly floatTitle: "MCP 管理器(点击展开)";
35
+ readonly floatManage: "管理";
36
+ readonly floatGlobalSession: "全局会话";
37
+ readonly groupProject: "项目级";
38
+ readonly groupGlobal: "全局";
39
+ readonly badgeScopeProject: "项目";
40
+ readonly badgeScopeGlobal: "全局";
41
+ readonly serverMeta: "{status} · {tools} 工具";
42
+ readonly toolsCount: "工具({n})";
43
+ readonly toolsCountPlain: "{n} 工具";
44
+ readonly statusGroupCount: "{status}({n})";
45
+ readonly groupAttention: "需关注({n})";
46
+ readonly healthRunning: "运行中 {n}";
47
+ readonly healthConnecting: "连接中 {n}";
48
+ readonly healthStopped: "未连接 {n}";
49
+ readonly healthFailed: "失败 {n}";
50
+ readonly floatEmptyTitle: "还没有 MCP 服务器";
51
+ readonly floatEmptyCta: "去添加";
52
+ readonly panelTitle: "MCP 管理器";
53
+ readonly tabServers: "服务器";
54
+ readonly tabQuickAdd: "快速接入";
55
+ readonly countsConnected: "运行中 {n}";
56
+ readonly countsConnecting: "连接中 {n}";
57
+ readonly countsFailed: "失败 {n}";
58
+ readonly countsSummary: "共 {n} 台 · {parts}";
59
+ readonly countsSummaryOnly: "共 {n} 台";
60
+ readonly addServer: "添加服务器";
61
+ readonly editServer: "编辑服务器:{name}";
62
+ readonly nameLabel: "服务器名称(唯一,作为 mcp__<name>__ 前缀)";
63
+ readonly ownershipLabel: "归属";
64
+ readonly transportLabel: "传输类型";
65
+ readonly commandLabel: "命令(stdio)";
66
+ readonly argsLabel: "参数(逗号分隔)";
67
+ readonly envLabel: "环境变量(每行 KEY=VALUE,支持 ${ENV} 引用,值为空则继承父环境)";
68
+ readonly cwdLabel: "工作目录(可选)";
69
+ readonly urlLabel: "URL(streamable-http)";
70
+ readonly headersLabel: "请求头(每行 KEY: VALUE,支持 ${ENV} 引用)";
71
+ readonly enabledLabel: "启用(保存后立即连接)";
72
+ readonly scopeProjectOpt: "项目级(<项目>/.dsh/dsh-mcp-manager/mcp.json,随会话切换)";
73
+ readonly scopeGlobalOpt: "全局(本机配置)";
74
+ readonly transportStdioOpt: "stdio(本地子进程)";
75
+ readonly transportHttpOpt: "streamable-http(远程)";
76
+ readonly envPlaceholder: "每行 KEY=VALUE,如\nCONTEXT7_API_KEY=${CONTEXT7_API_KEY}";
77
+ readonly headersPlaceholder: "每行 KEY: VALUE,支持 ${ENV} 引用,如\nAuthorization: Bearer ${CONTEXT7_API_KEY}";
78
+ readonly cwdPlaceholder: "可选工作目录";
79
+ readonly sourcesTitle: "mcp.json 配置文件(保存即互斥同步)";
80
+ readonly srcGlobalAgents: "全局 .agents/mcp.json";
81
+ readonly srcGlobalDsh: "全局 .dsh/mcp.json";
82
+ readonly srcProjectAgents: "项目 .agents/mcp.json";
83
+ readonly srcProjectDsh: "项目 .dsh/mcp.json";
84
+ readonly srcNotExists: "尚不存在,保存时创建";
85
+ readonly srcNeedSession: "需要项目会话后可用";
86
+ readonly srcUngrouped: "其他(未声明来源)";
87
+ readonly srcQuickSetup: "快速配置该来源";
88
+ readonly srcEdit: "编辑";
89
+ readonly srcSave: "保存并同步";
90
+ readonly srcSavedOk: "已保存并同步:{names}";
91
+ readonly srcMutexRemoved: "互斥移除同名:{names}";
92
+ readonly srcActivateThis: "启用此来源";
93
+ readonly jsonNameFixed: "JSON 里的 name 不可改(如需改名请删除后新建)";
94
+ readonly pasteTitle: "粘贴 mcpServers JSON 导入";
95
+ readonly importJson: "导入 JSON";
96
+ readonly importFromFile: "从 mcp.json 文件导入";
97
+ readonly importPathPlaceholder: "或填 mcp.json 文件路径导入,如 ~/.claude/mcp.json";
98
+ readonly importedOk: "已导入:{names}";
99
+ readonly importedNone: "(无)";
100
+ readonly importSkipped: "跳过(已存在):{names}";
101
+ readonly importFail: "导入失败:{msg}";
102
+ readonly serversEmpty: "还没有配置 MCP 服务器。切到「快速接入」页添加,或粘贴 mcpServers JSON 导入。";
103
+ readonly confirmDelete: "删除 MCP 服务器「{name}」?";
104
+ readonly settingsLoading: "MCP 管理器:加载中…";
105
+ readonly settingsName: "MCP 管理器(dsh-mcp-manager)";
106
+ readonly settingsDescription: "浮窗位置 / 水平·垂直·空白偏移";
107
+ readonly anchorLabel: "锚点";
108
+ readonly posTopRight: "右上(top-right)";
109
+ readonly posTopLeft: "左上(top-left)";
110
+ readonly posBottomRight: "右下(bottom-right)";
111
+ readonly posBottomLeft: "左下(bottom-left)";
112
+ readonly offsetX: "水平偏移";
113
+ readonly offsetY: "垂直偏移";
114
+ readonly blankY: "空白偏移";
115
+ readonly zIndexBase: "层级基准";
116
+ readonly settingsHint: "保存即热更新:浮窗位置与偏移即时生效并持久化(无需重启 dsh web)。";
117
+ readonly savingNow: "保存中…";
118
+ readonly settingsSavedOk: "已保存——浮窗位置即时生效(无需重启)";
119
+ };
120
+ /** 字典 key 并集(LocaleNamespaceMap 声明合并用)。 */
121
+ export type McpLocaleKey = keyof typeof zh;
122
+ /** 英文词典:必须与 zh key 完整对齐。 */
123
+ export declare const en: Record<McpLocaleKey, string>;
@@ -0,0 +1,47 @@
1
+ /**
2
+ * dsh-mcp-manager — 插件行配置页(SettingsCard)。
3
+ *
4
+ * 浮窗位置 / 偏移编辑区,React 组件(经 build-client externals 注入)。
5
+ * 读/写走 /api/dsh-mcp/config(GET 读 / POST 写),保存后经 SSE 热更新。
6
+ * 注册面:plugins.row.config,由 index.ts 装配。
7
+ */
8
+ import * as React from "react";
9
+ import type { PluginConfigViewProps } from "@deepseek-ai/dsh-client-ui-plugin-manager/client";
10
+ /**
11
+ * plugins.row.config owner 传给组件的视图与表单能力:官方 `PluginConfigViewProps`
12
+ * (dsh-client-ui-plugin-manager,plugins.row.config / plugins.bundle.config /
13
+ * plugins.item 三个 seat 的 owner 形状)原样透传,不另立镜像。
14
+ *
15
+ * 事实记录:**本组件不读 props.form**——页面读写走自身的 /api/dsh-mcp/config
16
+ * (GET 读 / POST 写,见下 SettingsPage),props.form 只是类型面上随 owner 契约到达。
17
+ * 换官方类型不改变渲染行为,也不因「用上了 form」而新增任何读取。
18
+ */
19
+ export type SettingsCardProps = PluginConfigViewProps;
20
+ /**
21
+ * summary 由插件行自身呈现;此组件不发配置/健康请求,也不返回嵌套 page DOM。
22
+ * page 挂载独立表单组件,切换视图时也不会跨分支改变 Hook 顺序。
23
+ *
24
+ * 【R3 原语层接入:只迁 Button】
25
+ * 保存按钮改用 <Button className="dm-set-save">——Button 原语在共享块里**一条规则都不出**
26
+ * (视觉由调用点传入的领域类承担),故这是纯增益:拿到 dsu-btn / data-dsu-btn 钩子与恒定
27
+ * 的 type="button",像素零变化。
28
+ *
29
+ * 下面四族**刻意不迁**,理由逐条钉住(防止被当成漏项「顺手补上」):
30
+ * 1. dm-set-field + dm-set-input:dm-set-field 是 inline-flex 纵向堆叠(标签在上),
31
+ * dsu-field 是 nowrap 横排;dm-set-input min-width 88 + padding 5px 8px,dsu-input 是
32
+ * margin-left 6 + padding 2px 6px。NumberField 的输入期钳制虽与本卡 numInput 等价,
33
+ * 但整体搬过去就是视觉改版,不在收敛范围。
34
+ * 2. dm-set-row:flex + align-center + margin 0,dsu-field-row 多一条 margin-bottom 8px。
35
+ * 3. dm-set-card:dsu-surface-card 带 max-width 560 + box-shadow + bg-base(本卡是
36
+ * bg-layer-3 + border-l2),两档都会改这张卡的观感。
37
+ * 4. dm-set-hint / dm-set-foot / dm-set-saved / dm-set-error:本卡领域件,T1 无同构原语
38
+ * (saved/error 是纯文字反馈行,不是 Badge/Status 点)。
39
+ * 另:dm-set-head / -headText / -name / -description / -chevron / -chevronOpen 六条规则在
40
+ * 本卡**零渲染**,但被 test/e2e/smoke.test.ts 的 #219 视觉锚点断言按 CSS 文本钉住,
41
+ * 删它必须改那条断言——属改判据而非收敛,故原样保留(决策权留给维护者)。
42
+ *
43
+ * 【边界】本文件只管这张 React 卡。浮窗(src/client/float/**、index.ts 的 panelHtml
44
+ * 命令式 DOM 链路、1300+ 条 dm-float-* 规则)不是 React,接不了原语层,是独立议题:
45
+ * 本轮一字不动。
46
+ */
47
+ export declare function SettingsCard(props: SettingsCardProps): React.ReactElement | null;