dsh-plugin-mcp-toggles 0.1.1 → 0.1.2

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 (2) hide show
  1. package/lib/client.js +90 -56
  2. package/package.json +1 -1
package/lib/client.js CHANGED
@@ -38,6 +38,7 @@ window.__ModuleLoader__.load({
38
38
  'picker.summary.all': '全部开启',
39
39
  'picker.summary.none': '全部关闭',
40
40
  'picker.summary.pending': '选择 MCP',
41
+ 'picker.summary.empty': '无',
41
42
  'picker.saving': '保存中…',
42
43
  'picker.unsaved': '未写入磁盘',
43
44
  }
@@ -61,6 +62,7 @@ window.__ModuleLoader__.load({
61
62
  'picker.summary.all': 'All on',
62
63
  'picker.summary.none': 'All off',
63
64
  'picker.summary.pending': 'MCP',
65
+ 'picker.summary.empty': 'None',
64
66
  'picker.saving': 'Saving…',
65
67
  'picker.unsaved': 'not written to disk',
66
68
  }
@@ -130,7 +132,7 @@ window.__ModuleLoader__.load({
130
132
  /** 小箭头。 */
131
133
  function Caret() {
132
134
  return React.createElement('svg', {
133
- width: 10, height: 10, viewBox: '0 0 24 24', fill: 'none', 'aria-hidden': true,
135
+ width: 12, height: 12, viewBox: '0 0 24 24', fill: 'none', 'aria-hidden': true,
134
136
  }, React.createElement('path', {
135
137
  d: 'm6 9 6 6 6-6',
136
138
  stroke: 'currentColor', strokeWidth: 2.2, strokeLinecap: 'round', strokeLinejoin: 'round',
@@ -139,90 +141,120 @@ window.__ModuleLoader__.load({
139
141
 
140
142
  // #endregion
141
143
 
142
- // 与同区域的系统按钮(open-in-app / agent-terminal / schedule-catalog)保持
143
- // 同一套尺寸:高 24px、字号 11px、0.5px 边框、--dsw-radius-sm。
144
+ // 样式基准取自 DSH 自身,数值与相邻控件对齐:
145
+ // · 标题栏正文 14px/20px、圆角 12px、hover 用 --dsw-alias-interactive-bg-hover
146
+ // (ui-conversation/ConversationRoot.module.css 的 .crumb)
147
+ // · hero 行控件 28px 高、24px 圆角、13px 字号、透明底
148
+ // (ui-conversation/PermissionSelect.module.css 的 .trigger)
149
+ // · 开关 20×10、thumb 6px、缓动 --ds-ease-in-out
150
+ // (ui-trajectory/TrajectoryToolbar.module.css 的 .controlTrack)
151
+ // · 浮层阴影用 --dsw-shadow-lv3,不写死 rgba
152
+ // 只用主题 token,不引入任何硬编码颜色。
144
153
  const STYLE = `
145
154
  .mt-wrap { position: relative; display: inline-flex; flex: none; align-self: center; }
146
155
  .mt-trigger {
147
- box-sizing: border-box; display: inline-flex; align-items: center; gap: 4px;
148
- height: 24px; padding: 3px 6px; max-width: 190px;
149
- border: .5px solid var(--dsw-alias-border-l4); border-radius: var(--dsw-radius-sm);
150
- background: 0 0; color: var(--dsw-alias-label-primary);
151
- font-family: var(--dsw-font-family); font-size: 11px; line-height: 16px;
156
+ box-sizing: border-box; display: inline-flex; align-items: center; gap: 6px;
157
+ height: 28px; padding: 0 8px; max-width: 220px;
158
+ border: none; border-radius: 24px; outline: none;
159
+ background: transparent; color: var(--dsw-alias-label-secondary);
160
+ font-family: var(--dsw-font-family); font-size: 13px; line-height: 20px; font-weight: 500;
152
161
  white-space: nowrap; cursor: pointer;
153
162
  }
154
- .mt-trigger:hover { background: var(--dsw-alias-interactive-bg-hover); }
155
- .mt-trigger:focus-visible { background: var(--dsw-alias-interactive-bg-hover); outline: none; }
156
- .mt-trigger[data-open="true"] { border-color: var(--dsw-alias-border-l2); background: var(--dsw-alias-interactive-bg-hover); }
157
- .mt-trigger[data-partial="true"] { color: var(--dsw-alias-state-warn-primary); }
158
- .mt-trigger[data-none="true"] { color: var(--dsw-alias-label-secondary); }
159
- /* 新会话落地页那一行比标题栏更矮更紧凑,和相邻的 workspace/preset 控件同高。 */
160
- .mt-trigger[data-compact="true"] { height: 22px; padding: 2px 6px; font-size: 10.5px; }
161
- .mt-link[data-disabled="true"] { opacity: .5; cursor: default; pointer-events: none; }
162
- .mt-icon { flex: none; display: inline-flex; align-items: center; opacity: .9; }
163
+ .mt-trigger:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); }
164
+ .mt-trigger:focus-visible { box-shadow: 0 0 0 2px var(--dsw-alias-border-l3); }
165
+ .mt-trigger[data-open="true"] { background: var(--dsw-alias-interactive-bg-hover); }
166
+ .mt-trigger[data-none="true"] { color: var(--dsw-alias-label-dimmed); }
167
+ /* 部分关闭:用状态色点出「本会话少了东西」,而不是整块文字变色。 */
168
+ .mt-trigger[data-partial="true"] .mt-name { color: var(--dsw-alias-label-primary); }
169
+ .mt-trigger[data-partial="true"] .mt-badge { color: var(--dsw-alias-state-warn-primary); }
170
+ /* hero 行比标题栏紧凑,与相邻的 workspace/模式控件同高。 */
171
+ .mt-trigger[data-compact="true"] { height: 28px; padding: 0 8px; font-size: 13px; }
172
+ .mt-icon { flex: none; display: inline-flex; align-items: center; }
163
173
  .mt-name { overflow: hidden; text-overflow: ellipsis; }
164
- .mt-caret { flex: none; display: inline-flex; align-items: center; color: var(--dsw-alias-label-secondary); transition: transform .12s ease; }
174
+ .mt-caret {
175
+ flex: none; display: inline-flex; align-items: center;
176
+ color: var(--dsw-alias-label-caption);
177
+ transition: transform 120ms var(--ds-ease-in-out);
178
+ }
165
179
  .mt-trigger[data-open="true"] .mt-caret { transform: rotate(180deg); }
180
+ .mt-badge {
181
+ flex: none; padding: 0 6px; border-radius: 6px;
182
+ font-size: 12px; line-height: 18px; font-weight: 500;
183
+ background: var(--dsw-alias-bg-layer-2); color: var(--dsw-alias-label-secondary);
184
+ }
185
+ .mt-badge[data-tone="warn"] { color: var(--dsw-alias-state-warn-primary); }
186
+
187
+ /* 浮层:与 DSH 弹层同源 —— overlay 底、lv3 阴影、12px 圆角。 */
166
188
  .mt-menu {
167
- position: absolute; top: calc(100% + 5px); right: 0; z-index: 60;
168
- width: 330px; max-height: 60vh; overflow-y: auto; padding: 4px;
169
- border: .5px solid var(--dsw-alias-border-l2); border-radius: var(--dsw-radius-md);
170
- background: var(--dsw-alias-bg-overlay); box-shadow: 0 8px 24px rgba(0,0,0,.16);
189
+ position: absolute; top: calc(100% + 6px); right: 0; z-index: 60;
190
+ width: 340px; max-height: 60vh; overflow-y: auto; padding: 6px;
191
+ border: 1px solid var(--dsw-alias-border-l1); border-radius: 12px;
192
+ background: var(--dsw-alias-bg-overlay); box-shadow: var(--dsw-shadow-lv3);
171
193
  }
172
194
  .mt-head {
173
195
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
174
- padding: 5px 8px 6px; font-size: 11px; line-height: 16px;
196
+ padding: 6px 8px 8px;
197
+ font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-secondary);
198
+ }
199
+ .mt-headActions { display: inline-flex; align-items: center; gap: 10px; flex: none; }
200
+ .mt-link {
201
+ cursor: pointer; border-radius: 6px; padding: 0 2px;
175
202
  color: var(--dsw-alias-label-secondary);
203
+ transition: color 120ms var(--ds-ease-in-out);
176
204
  }
177
- .mt-headActions { display: inline-flex; align-items: center; gap: 8px; flex: none; }
178
- .mt-link { cursor: pointer; color: var(--dsw-alias-label-secondary); }
179
205
  .mt-link:hover { color: var(--dsw-alias-brand-primary); }
206
+ .mt-link:focus-visible { outline: 2px solid var(--dsw-alias-border-l3); outline-offset: 1px; }
207
+ .mt-link[data-disabled="true"] { opacity: .5; cursor: default; pointer-events: none; }
180
208
  .mt-item {
181
- display: flex; align-items: center; gap: 8px; padding: 6px 8px;
182
- border-radius: var(--dsw-radius-sm); cursor: pointer;
209
+ display: flex; align-items: center; gap: 10px; padding: 8px;
210
+ border-radius: 8px; cursor: default;
183
211
  }
184
212
  .mt-item:hover { background: var(--dsw-alias-interactive-bg-hover); }
185
- .mt-item[data-busy="true"] { opacity: .6; cursor: default; }
213
+ .mt-item[data-busy="true"] { opacity: .6; }
186
214
  .mt-body { flex: 1; min-width: 0; }
187
- .mt-title { display: flex; align-items: center; gap: 5px; font-size: 11px; line-height: 16px; color: var(--dsw-alias-label-primary); }
215
+ .mt-title {
216
+ display: flex; align-items: center; gap: 6px;
217
+ font-size: 13px; line-height: 20px; font-weight: 500;
218
+ color: var(--dsw-alias-label-primary);
219
+ }
188
220
  .mt-sub {
189
- margin-top: 1px; font-size: 10px; line-height: 14px;
221
+ margin-top: 2px; font-size: 12px; line-height: 18px;
190
222
  color: var(--dsw-alias-label-secondary);
191
223
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
192
224
  }
193
- .mt-badge {
194
- flex: none; padding: 0 4px; border-radius: var(--dsw-radius-xs);
195
- font-size: 9.5px; line-height: 14px;
196
- background: var(--dsw-alias-bg-layer-2); color: var(--dsw-alias-label-secondary);
197
- }
198
- .mt-badge[data-tone="warn"] { color: var(--dsw-alias-state-warn-primary); }
199
225
  .mt-switch {
200
226
  flex: none; position: relative; box-sizing: border-box;
201
- width: 26px; height: 15px; padding: 0; border-radius: 999px;
202
- border: .5px solid var(--dsw-alias-border-l2);
203
- background: var(--dsw-alias-bg-layer-2); cursor: pointer; transition: background .12s ease;
227
+ width: 32px; height: 18px; padding: 0;
228
+ border: none; border-radius: 9px;
229
+ background: var(--dsw-alias-border-l2); cursor: pointer;
230
+ transition: background-color 120ms var(--ds-ease-in-out);
204
231
  }
205
232
  .mt-switch::after {
206
- content: ""; position: absolute; top: 1.5px; left: 2px;
207
- width: 10px; height: 10px; border-radius: 50%;
208
- background: var(--dsw-alias-label-secondary); transition: transform .12s ease, background .12s ease;
233
+ content: ""; position: absolute; top: 3px; left: 3px;
234
+ width: 12px; height: 12px; border-radius: 50%;
235
+ background: var(--dsw-alias-bg-layer-1);
236
+ transition: transform 120ms var(--ds-ease-in-out);
209
237
  }
210
- .mt-switch[aria-checked="true"] { background: var(--dsw-alias-brand-primary); border-color: var(--dsw-alias-brand-primary); }
211
- .mt-switch[aria-checked="true"]::after { transform: translateX(11px); background: var(--dsw-alias-bg-base); }
212
- .mt-switch:focus-visible { outline: 2px solid var(--dsw-alias-brand-primary); outline-offset: 1px; }
238
+ .mt-switch[aria-checked="true"] { background: var(--dsw-alias-brand-primary); }
239
+ .mt-switch[aria-checked="true"]::after { transform: translateX(14px); }
240
+ .mt-switch:focus-visible { outline: 2px solid var(--dsw-alias-border-l3); outline-offset: 2px; }
213
241
  .mt-switch:disabled { opacity: .5; cursor: default; }
214
- .mt-sep { height: .5px; margin: 4px 2px; background: var(--dsw-alias-border-l1); }
215
242
  .mt-foot {
216
- display: flex; align-items: center; gap: 6px; padding: 5px 8px;
217
- font-size: 10.5px; line-height: 15px; color: var(--dsw-alias-label-secondary);
243
+ display: flex; align-items: center; gap: 6px; padding: 6px 8px;
244
+ font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-secondary);
245
+ }
246
+ .mt-err {
247
+ padding: 4px 8px 6px; font-size: 12px; line-height: 18px;
248
+ color: var(--dsw-alias-state-error-primary);
218
249
  }
219
- .mt-err { padding: 3px 8px 6px; font-size: 10.5px; line-height: 15px; color: var(--dsw-alias-state-error-primary); }
220
250
  .mt-btn {
221
- padding: 3px 8px; border: .5px solid var(--dsw-alias-border-l2); border-radius: var(--dsw-radius-sm);
222
- background: 0 0; color: var(--dsw-alias-label-primary);
223
- font-family: var(--dsw-font-family); font-size: 11px; line-height: 16px; cursor: pointer;
251
+ padding: 4px 10px; border: 1px solid var(--dsw-alias-border-l2); border-radius: 8px;
252
+ background: transparent; color: var(--dsw-alias-label-primary);
253
+ font-family: var(--dsw-font-family); font-size: 12px; line-height: 18px;
254
+ cursor: pointer; transition: background-color 120ms var(--ds-ease-in-out);
224
255
  }
225
- .mt-btn:hover { background: var(--dsw-alias-interactive-bg-hover); }
256
+ .mt-btn:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); }
257
+ .mt-btn:focus-visible { outline: 2px solid var(--dsw-alias-border-l3); outline-offset: 1px; }
226
258
  .mt-btn:disabled { opacity: .5; cursor: default; }
227
259
  `
228
260
 
@@ -301,12 +333,14 @@ window.__ModuleLoader__.load({
301
333
  const servers = data?.servers ?? []
302
334
  const enabledCount = data?.enabledCount ?? 0
303
335
 
336
+ // 徽标只放短状态:长句(无服务器/读取中)会把 220px 的触发器撑破,
337
+ // 完整说明留在弹层里。
304
338
  const label = !scoped
305
339
  ? t('picker.summary.pending')
306
340
  : data === undefined
307
- ? t('picker.loading')
341
+ ? '…'
308
342
  : servers.length === 0
309
- ? t('picker.empty')
343
+ ? t('picker.summary.empty')
310
344
  : enabledCount === servers.length
311
345
  ? t('picker.summary.all')
312
346
  : enabledCount === 0
@@ -378,7 +412,7 @@ window.__ModuleLoader__.load({
378
412
  'aria-expanded': open,
379
413
  onClick: () => { setOpen((value) => !value) },
380
414
  },
381
- React.createElement('span', { className: 'mt-icon' }, React.createElement(PlugGlyph, { size: 13 })),
415
+ React.createElement('span', { className: 'mt-icon' }, React.createElement(PlugGlyph, { size: 14 })),
382
416
  React.createElement('span', { className: 'mt-name' }, 'MCP'),
383
417
  React.createElement('span', {
384
418
  className: 'mt-badge',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-plugin-mcp-toggles",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "type": "module",
5
5
  "description": "Turn installed MCP servers on or off per conversation, from a picker in the session header.",
6
6
  "keywords": [