dsh-data-cleaning-agent 0.8.7 → 0.8.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,26 @@
2
2
 
3
3
  本文件记录 `dsh-data-cleaning-agent` 的版本变更。格式遵循 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/),版本号遵循 [SemVer](https://semver.org/lang/zh-CN/)。
4
4
 
5
+ ## [0.8.9] - 2026-09-07
6
+
7
+ ### Changed
8
+ - 按共享 DSH-UX-001 v1.1.2 对齐招投标工作台的阶段菜单:单行五个等宽分栏、上图标下短标题、分隔线及选中蓝色底线;取消数字前缀和横向滚动布局。说明与状态仅保留在内容区和工作台头部。
9
+ - 窄屏缩小图标与字号,长标题在分栏内省略并保留完整可访问名称和悬停提示;阶段导航、质量体检子视图及 Host 工作流保持不变。
10
+
11
+ ### Tests
12
+ - 增补五阶段图标/标题结构断言与隔离 Chromium 深浅色布局回归,覆盖 320px 窄屏、普通/展开工作台、长标题防溢出,以及切换阶段不修改 Host 任务。
13
+
14
+ ## [0.8.8] - 2026-09-06
15
+
16
+ ### Changed
17
+ - 按共享 DSH-UX-001 v1.1.0 企查查蓝方案调整自有界面,统一浅色/深色颜色令牌、紧凑分区、浅蓝表头和键盘焦点;不更改宿主原生输入框、模型及发送机制。
18
+ - 入口、首页、会话头和工作台采用统一数据库线性图标;首页 LOGO 与名称同排。会话级可恢复 Bridge 不注册全局单例品牌槽位,离开首页恢复宿主标题、图标和预览标识。
19
+ - 当前任务/任务历史使用下划线管理标签,五步流程为横向可滚动紧凑导航;快捷菜单仍在原生输入框外下方。
20
+ - 向导与工作台按维度展示字段勾选网格,支持中文字段/维度/工具名称搜索,搜索不会丢失已选字段。维度全选/清空作用于完整维度,不受搜索过滤影响;128 字段与 Host 工作流不变。
21
+
22
+ ### Tests
23
+ - 增补数据库图标、字段过滤、全局槽位隔离与真实 React/Chromium 同排排版、深浅色按钮、字段选择保持、回填发送和宿主图标恢复检查。具体边界见 `docs/QCC-BLUE-UI-ACCEPTANCE.md`。
24
+
5
25
  ## [0.8.7] - 2026-09-06
6
26
 
7
27
  ### Changed
package/README.en.md CHANGED
@@ -2,7 +2,9 @@
2
2
 
3
3
  > A data cleaning & completion agent plugin for DeepSeek Harness: local CSV/XLSX/JSON engine plus optional Qichacha (QCC) MCP enterprise-data enrichment. Initiated and maintained by the Qichacha (QCC) team.
4
4
  >
5
- > Current source version / 当前源码版本: **0.8.7** (stable release)
5
+ > Current source version / 当前源码版本: **0.8.9** (stable release)
6
+
7
+ This release aligns the workbench stage menu with the tender agent: five equal-width columns in one row, line icons above short labels, and a pale-blue selection with a blue underline. Narrow layouts stay within the panel. All 128 fields, existing workflows, and native DSH input and send behavior are preserved.
6
8
 
7
9
  [![CI](https://github.com/duhu2000/dsh-data-cleaning-agent/actions/workflows/ci.yml/badge.svg)](https://github.com/duhu2000/dsh-data-cleaning-agent/actions/workflows/ci.yml)
8
10
  [![npm](https://img.shields.io/npm/v/dsh-data-cleaning-agent)](https://www.npmjs.com/package/dsh-data-cleaning-agent)
package/README.md CHANGED
@@ -2,7 +2,9 @@
2
2
 
3
3
  > 在 DeepSeek Harness 中清洗、补全、画像企业名单数据的智能体插件:本地 CSV/XLSX/JSON 引擎 + 可选企查查(Qichacha/QCC)MCP 企业数据补全,由企查查(Qichacha/QCC)团队发起并维护。
4
4
  >
5
- > 当前源码版本 / Current source version: **0.8.7**(正式版本)
5
+ > 当前源码版本 / Current source version: **0.8.9**(正式版本)
6
+
7
+ 本版将右侧阶段菜单对齐招投标工作台:单行五个等宽分栏、上图标下短标题,选中项采用浅蓝底和蓝色底线;窄屏不换行、不横向溢出。保留企查查蓝界面、全部 128 个字段和原有工作流,不替换 DSH 原生输入和发送机制。
6
8
 
7
9
  [![CI](https://github.com/duhu2000/dsh-data-cleaning-agent/actions/workflows/ci.yml/badge.svg)](https://github.com/duhu2000/dsh-data-cleaning-agent/actions/workflows/ci.yml)
8
10
  [![npm](https://img.shields.io/npm/v/dsh-data-cleaning-agent)](https://www.npmjs.com/package/dsh-data-cleaning-agent)
package/lib/client.js CHANGED
@@ -32,7 +32,6 @@ window.__ModuleLoader__.load({
32
32
  IconArchiveOutline20,
33
33
  IconChecklistOutline14,
34
34
  IconCloseOutline16,
35
- IconDataOutline16,
36
35
  IconDownloadOutline16,
37
36
  IconFullscreenOutline16,
38
37
  IconPaperclipOutline16,
@@ -55,6 +54,37 @@ window.__ModuleLoader__.load({
55
54
 
56
55
  const h = react.createElement;
57
56
 
57
+ // 同一数据库图形用于入口、业务首页和工作台;不注册 root/single 品牌槽位。
58
+ const DATABASE_PATH = 'M4 6c0-4 16-4 16 0s-16 4-16 0v12c0 4 16 4 16 0V6M4 12c0 4 16 4 16 0';
59
+ function DatabaseLogo({ size = 20 } = {}) {
60
+ return h('svg', { width: size, height: size, viewBox: '0 0 24 24', fill: 'none',
61
+ stroke: 'currentColor', strokeWidth: 1.7, strokeLinecap: 'round', strokeLinejoin: 'round',
62
+ 'aria-hidden': true, focusable: false, className: 'dcAgentDatabaseLogo' },
63
+ h('path', { d: DATABASE_PATH }));
64
+ }
65
+
66
+ // 阶段只展示线性图标和短标题;说明、状态与操作保留在内容区。
67
+ const STAGE_ICON_PATHS = {
68
+ upload: 'M12 16V3m-4 4 4-4 4 4M4 14v6h16v-6',
69
+ check: 'M9 6h11M9 12h11M9 18h11M3 6l1 1 2-2M3 12l1 1 2-2M3 18l1 1 2-2',
70
+ search: 'M16 16l5 5M18 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0',
71
+ database: DATABASE_PATH,
72
+ table: 'M4 3h16v18H4zM4 8h16M4 13h16M4 17h16M10 8v13',
73
+ };
74
+ function StageIcon({ kind }) {
75
+ return h('svg', { width: 20, height: 20, viewBox: '0 0 24 24', fill: 'none',
76
+ stroke: 'currentColor', strokeWidth: 1.7, strokeLinecap: 'round', strokeLinejoin: 'round',
77
+ 'aria-hidden': true, focusable: false }, h('path', { d: STAGE_ICON_PATHS[kind] }));
78
+ }
79
+
80
+ // 搜索仅改变可见字段,绝不清除已选字段或改变 Host 的字段目录。
81
+ function visibleCatalogFields(group, query) {
82
+ const needle = String(query || '').trim().toLowerCase();
83
+ const [, label, fields, tool] = group;
84
+ if (!needle || `${label} ${tool || ''}`.toLowerCase().includes(needle)) return fields;
85
+ return fields.filter(([id, fieldLabel]) => `${id} ${fieldLabel}`.toLowerCase().includes(needle));
86
+ }
87
+
58
88
  /** 客户端所需服务:与 mcp-connector 对齐(槽位 + 会话/工作区/输入机)。 */
59
89
  const inject = ['slots', 'sessions', 'workspaces', 'conversation'];
60
90
 
@@ -62,6 +92,31 @@ window.__ModuleLoader__.load({
62
92
  const SIDEBAR_WORKSPACES_SELECTOR = '[data-slot="sidebar.workspaces"]';
63
93
  const TOP_MOUNT_SELECTOR = '[data-data-cleaning-top-mount="true"]';
64
94
  const stylesCss = `
95
+ /* QCC-blue candidate tokens from shared DSH-UX-001; never theme the global shell. */
96
+ :where(.dcAgentTopMount, .dcAgentLauncher, .dcAgentExperience, .dcAgentCapabilityMount,
97
+ .dcAgentOverlay, .dcAgentPromptLayer, .dcAgentPromptBackdrop, .dcAgentHeaderAction,
98
+ .dcAgentToolCard, [data-dc-agent-hero-row="true"]) {
99
+ --dc-action: light-dark(#0875d1, #82c3ff);
100
+ --dc-hover: light-dark(#0666b7, #acd7ff);
101
+ --dc-on-action: light-dark(#fff, #101820);
102
+ --dc-selected: light-dark(#e6f4ff, #173449);
103
+ --dc-surface: light-dark(#fff, #18232e);
104
+ --dc-page: light-dark(#f6f8fa, #101820);
105
+ --dc-table-head: light-dark(#f2f9fc, #172c3b);
106
+ --dc-text: light-dark(#202c3b, #e7eef6);
107
+ --dc-muted: light-dark(#626f80, #a2b1c2);
108
+ --dc-border: light-dark(#dce4ec, #344657);
109
+ --dc-success: light-dark(#12805c, #78d8b3);
110
+ --dc-success-bg: light-dark(#edf8f2, #193a30);
111
+ --dc-review: light-dark(#946000, #f3c66c);
112
+ accent-color: var(--dc-action);
113
+ }
114
+ .dcAgentLauncherContent { display: inline-flex; align-items: center; gap: 8px; }
115
+ .dcAgentDatabaseLogo { display: block; flex: none; color: var(--dc-action); }
116
+ [data-dc-agent-hero-row="true"] { display: flex; align-items: center; justify-content: center; gap: 12px; }
117
+ [data-dc-agent-hero-title="true"] { min-width: 0; font-size: 28px; line-height: 1.3; color: var(--dc-text); }
118
+ .dcAgentHeroLogo { width: 48px; height: 48px; border-radius: 12px; background: var(--dc-selected); color: var(--dc-action); display: grid; place-items: center; flex: none; }
119
+
65
120
  .dcAgentTopMount {
66
121
  flex: none;
67
122
  min-width: 0;
@@ -118,10 +173,10 @@ window.__ModuleLoader__.load({
118
173
  max-width: calc(100vw - 420px);
119
174
  min-width: 360px;
120
175
  height: 100vh;
121
- border: 1px solid light-dark(#d5dae4, #2a3038);
176
+ border: 1px solid var(--dc-border);
122
177
  border-radius: 12px 0 0 12px;
123
- background: light-dark(#ffffff, #161b23);
124
- color: light-dark(#172033, #edf2fa);
178
+ background: var(--dc-surface);
179
+ color: var(--dc-text);
125
180
  box-shadow: light-dark(-10px 0 32px rgba(33, 55, 88, .12), -12px 0 40px rgba(0, 0, 0, .32));
126
181
  overflow: hidden;
127
182
  pointer-events: auto;
@@ -130,7 +185,7 @@ window.__ModuleLoader__.load({
130
185
 
131
186
  .dcAgentCapabilities {
132
187
  display: flex;
133
- justify-content: center;
188
+ justify-content: safe center;
134
189
  align-items: center;
135
190
  gap: 8px;
136
191
  width: 100%;
@@ -154,10 +209,10 @@ window.__ModuleLoader__.load({
154
209
  padding: 7px 12px;
155
210
  flex-direction: column;
156
211
  justify-content: center;
157
- border: 1px solid light-dark(#e4e8f0, #303947);
212
+ border: 1px solid var(--dc-border);
158
213
  border-radius: 12px;
159
- background: light-dark(rgba(255,255,255,.86), rgba(22,27,35,.86));
160
- color: light-dark(#5d687a, #aab5c7);
214
+ background: var(--dc-surface);
215
+ color: var(--dc-muted);
161
216
  font: inherit;
162
217
  font-size: 12px;
163
218
  cursor: pointer;
@@ -165,9 +220,9 @@ window.__ModuleLoader__.load({
165
220
  .dcAgentCapability:hover,
166
221
  .dcAgentCapability:focus-visible,
167
222
  .dcAgentCapability.is-active {
168
- border-color: light-dark(#c9d9f8, #365681);
169
- background: light-dark(#edf4ff, #172841);
170
- color: light-dark(#1556cf, #8cb3ff);
223
+ border-color: var(--dc-border);
224
+ background: var(--dc-selected);
225
+ color: var(--dc-action);
171
226
  }
172
227
  .dcAgentCapability svg { flex: 0 0 auto; }
173
228
 
@@ -178,7 +233,7 @@ window.__ModuleLoader__.load({
178
233
  box-sizing: border-box;
179
234
  }
180
235
  .dcAgentCapabilityMount { width: 100%; padding: 8px 0; flex: none; }
181
- .dcAgentHomeSummary { margin: 0 20px 8px; text-align: center; color: light-dark(#697386, #aab5c7); font-size: 13px; line-height: 20px; }
236
+ .dcAgentHomeSummary { margin: 0 20px 8px; text-align: center; color: var(--dc-muted); font-size: 13px; line-height: 20px; }
182
237
  .dcAgentPromptBackdrop { position: fixed; inset: 0; z-index: 2000; display: grid; place-items: center; padding: 16px; box-sizing: border-box; background: rgba(8, 15, 28, .36); pointer-events: auto; }
183
238
  body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
184
239
 
@@ -199,10 +254,10 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
199
254
  left: 16px;
200
255
  min-height: 28px;
201
256
  padding: 3px 10px;
202
- border: 1px solid light-dark(#c9d9f8, #365681);
257
+ border: 1px solid var(--dc-border);
203
258
  border-radius: 999px;
204
- background: light-dark(#edf4ff, #172841);
205
- color: light-dark(#1556cf, #8cb3ff);
259
+ background: var(--dc-selected);
260
+ color: var(--dc-action);
206
261
  font: inherit;
207
262
  font-size: 12px;
208
263
  cursor: pointer;
@@ -217,16 +272,16 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
217
272
  box-sizing: border-box;
218
273
  overflow: hidden;
219
274
  padding: 16px;
220
- border: 1px solid light-dark(#d5dae4, #303947);
221
- border-radius: 16px;
222
- background: light-dark(#ffffff, #161b23);
223
- color: light-dark(#172033, #edf2fa);
275
+ border: 1px solid var(--dc-border);
276
+ border-radius: 12px;
277
+ background: var(--dc-surface);
278
+ color: var(--dc-text);
224
279
  box-shadow: light-dark(0 18px 48px rgba(33,55,88,.20), 0 20px 54px rgba(0,0,0,.40));
225
280
  pointer-events: auto;
226
281
  }
227
282
  .dcAgentPromptBody { min-height: 0; overflow: auto; overscroll-behavior: contain; padding: 0 2px; }
228
283
  .dcAgentPromptHead, .dcAgentPromptActions { flex: none; }
229
- .dcAgentPromptActions { border-top: 1px solid light-dark(#e4e8f0, #303947); padding-top: 12px; }
284
+ .dcAgentPromptActions { border-top: 1px solid var(--dc-border); padding-top: 12px; }
230
285
  .dcAgentPromptHead {
231
286
  display: flex;
232
287
  align-items: flex-start;
@@ -235,7 +290,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
235
290
  margin-bottom: 12px;
236
291
  }
237
292
  .dcAgentPromptHead h3 { margin: 0; font-size: 16px; line-height: 22px; }
238
- .dcAgentPromptHead p { margin: 3px 0 0; color: light-dark(#697386, #aab5c7); font-size: 11px; line-height: 17px; }
293
+ .dcAgentPromptHead p { margin: 3px 0 0; color: var(--dc-muted); font-size: 12px; line-height: 17px; }
239
294
  .dcAgentPromptClose {
240
295
  width: 28px;
241
296
  height: 28px;
@@ -246,7 +301,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
246
301
  color: inherit;
247
302
  cursor: pointer;
248
303
  }
249
- .dcAgentPromptClose:hover { background: light-dark(#f1f4f8, #222a36); }
304
+ .dcAgentPromptClose:hover { background: var(--dc-page); }
250
305
  .dcAgentPromptTabs { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
251
306
  .dcAgentPromptTab,
252
307
  .dcAgentPromptChoice {
@@ -255,8 +310,8 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
255
310
  gap: 5px;
256
311
  min-height: 32px;
257
312
  padding: 5px 10px;
258
- border: 1px solid light-dark(#d9dee8, #394352);
259
- border-radius: 9px;
313
+ border: 1px solid var(--dc-border);
314
+ border-radius: 6px;
260
315
  background: transparent;
261
316
  color: inherit;
262
317
  font: inherit;
@@ -265,9 +320,9 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
265
320
  }
266
321
  .dcAgentPromptTab.is-active,
267
322
  .dcAgentPromptChoice.is-selected {
268
- border-color: light-dark(#2869e6, #6d9eff);
269
- background: light-dark(#edf4ff, #172841);
270
- color: light-dark(#1556cf, #8cb3ff);
323
+ border-color: var(--dc-action);
324
+ background: var(--dc-selected);
325
+ color: var(--dc-action);
271
326
  }
272
327
  .dcAgentPromptField { display: grid; gap: 6px; margin: 10px 0; }
273
328
  .dcAgentPromptField > span { font-size: 12px; font-weight: 600; }
@@ -277,9 +332,9 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
277
332
  min-height: 104px;
278
333
  resize: vertical;
279
334
  padding: 10px 12px;
280
- border: 1px solid light-dark(#d9dee8, #394352);
281
- border-radius: 10px;
282
- background: light-dark(#fbfcfe, #11171f);
335
+ border: 1px solid var(--dc-border);
336
+ border-radius: 8px;
337
+ background: var(--dc-page);
283
338
  color: inherit;
284
339
  font: inherit;
285
340
  font-size: 12px;
@@ -291,8 +346,8 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
291
346
  gap: 10px;
292
347
  padding: 12px;
293
348
  border: 1px dashed light-dark(#b9c5d8, #43516a);
294
- border-radius: 10px;
295
- color: light-dark(#59677c, #b1bdd0);
349
+ border-radius: 8px;
350
+ color: var(--dc-muted);
296
351
  font-size: 12px;
297
352
  }
298
353
  .dcAgentPromptFile input { max-width: 100%; }
@@ -302,17 +357,17 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
302
357
  padding: 12px;
303
358
  border: 1px dashed light-dark(#b9c5d8, #43516a);
304
359
  border-radius: 12px;
305
- background: light-dark(#fbfcfe, #11171f);
360
+ background: var(--dc-page);
306
361
  outline: none;
307
362
  }
308
363
  .dcAgentPromptImageDrop.is-active {
309
- border-color: #2869e6;
310
- background: light-dark(#edf4ff, #172841);
364
+ border-color: var(--dc-action);
365
+ background: var(--dc-selected);
311
366
  }
312
367
  .dcAgentPromptImageDrop > p {
313
368
  margin: 0;
314
- color: light-dark(#697386, #aab5c7);
315
- font-size: 11px;
369
+ color: var(--dc-muted);
370
+ font-size: 12px;
316
371
  line-height: 17px;
317
372
  }
318
373
  .dcAgentPromptImagePreview {
@@ -327,25 +382,25 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
327
382
  flex: 0 0 auto;
328
383
  overflow: hidden;
329
384
  padding: 0;
330
- border: 1px solid light-dark(#d9dee8, #394352);
331
- border-radius: 10px;
332
- background: light-dark(#f3f6fa, #202733);
385
+ border: 1px solid var(--dc-border);
386
+ border-radius: 8px;
387
+ background: var(--dc-page);
333
388
  cursor: zoom-in;
334
389
  }
335
390
  .dcAgentPromptImageThumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
336
391
  .dcAgentPromptImageMeta { min-width: 0; flex: 1 1 auto; }
337
392
  .dcAgentPromptImageMeta b,
338
393
  .dcAgentPromptImageMeta small { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
339
- .dcAgentPromptImageMeta small { margin-top: 3px; color: light-dark(#697386, #aab5c7); }
394
+ .dcAgentPromptImageMeta small { margin-top: 3px; color: var(--dc-muted); }
340
395
  .dcAgentPromptImageRemove {
341
396
  flex: 0 0 auto;
342
397
  padding: 5px 9px;
343
- border: 1px solid light-dark(#d9dee8, #394352);
398
+ border: 1px solid var(--dc-border);
344
399
  border-radius: 8px;
345
400
  background: transparent;
346
401
  color: inherit;
347
402
  font: inherit;
348
- font-size: 11px;
403
+ font-size: 12px;
349
404
  cursor: pointer;
350
405
  }
351
406
  .dcAgentImageLightbox {
@@ -376,25 +431,25 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
376
431
  margin: 10px 0 0;
377
432
  padding: 8px 10px;
378
433
  border-radius: 8px;
379
- background: light-dark(#f6f8fb, #1c2330);
380
- color: light-dark(#697386, #aab5c7);
381
- font-size: 11px;
434
+ background: var(--dc-page);
435
+ color: var(--dc-muted);
436
+ font-size: 12px;
382
437
  line-height: 17px;
383
438
  }
384
- .dcAgentPromptError { margin: 8px 0 0; color: light-dark(#b42318, #ff8d86); font-size: 11px; }
439
+ .dcAgentPromptError { margin: 8px 0 0; color: light-dark(#b42318, #ff8d86); font-size: 12px; }
385
440
  .dcAgentPromptActions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 14px; }
386
441
  .dcAgentPromptAction {
387
442
  min-height: 34px;
388
443
  padding: 6px 13px;
389
- border: 1px solid light-dark(#d9dee8, #394352);
390
- border-radius: 9px;
444
+ border: 1px solid var(--dc-border);
445
+ border-radius: 6px;
391
446
  background: transparent;
392
447
  color: inherit;
393
448
  font: inherit;
394
449
  font-size: 12px;
395
450
  cursor: pointer;
396
451
  }
397
- .dcAgentPromptAction.is-primary { border-color: #2869e6; background: #2869e6; color: white; }
452
+ .dcAgentPromptAction.is-primary { border-color: var(--dc-action); background: var(--dc-action); color: var(--dc-on-action); }
398
453
  .dcAgentPromptAction:disabled { opacity: .5; cursor: default; }
399
454
 
400
455
  .dcAgentHeaderAction {
@@ -403,9 +458,9 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
403
458
  gap: 6px;
404
459
  min-height: 30px;
405
460
  padding: 4px 9px;
406
- border: 1px solid light-dark(#d9dee8, #394352);
461
+ border: 1px solid var(--dc-border);
407
462
  border-radius: 8px;
408
- background: light-dark(#ffffff, #191f28);
463
+ background: var(--dc-surface);
409
464
  color: inherit;
410
465
  font: inherit;
411
466
  font-size: 12px;
@@ -413,8 +468,8 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
413
468
  }
414
469
  .dcAgentHeaderAction:hover,
415
470
  .dcAgentHeaderAction:focus-visible {
416
- border-color: light-dark(#2869e6, #6d9eff);
417
- color: light-dark(#1556cf, #8cb3ff);
471
+ border-color: var(--dc-action);
472
+ color: var(--dc-action);
418
473
  }
419
474
 
420
475
  .dcAgentWbHeader {
@@ -422,7 +477,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
422
477
  align-items: center;
423
478
  gap: 8px;
424
479
  padding: 12px 14px;
425
- border-bottom: 1px solid light-dark(#e4e8f0, #303947);
480
+ border-bottom: 1px solid var(--dc-border);
426
481
  }
427
482
 
428
483
  .dcAgentWbTitle {
@@ -439,15 +494,15 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
439
494
  display: grid;
440
495
  place-items: center;
441
496
  flex: 0 0 auto;
442
- border-radius: 11px;
497
+ border-radius: 8px;
443
498
  font-size: 18px;
444
- background: light-dark(#edf4ff, #172841);
499
+ background: var(--dc-selected);
445
500
  }
446
501
 
447
502
  .dcAgentWbTitle b,
448
503
  .dcAgentWbTitle small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
449
504
  .dcAgentWbTitle b { display: block; font-size: 15px; }
450
- .dcAgentWbTitle small { display: block; max-width: 190px; color: light-dark(#697386, #aab5c7); font-size: 11px; }
505
+ .dcAgentWbTitle small { display: block; max-width: 190px; color: var(--dc-muted); font-size: 12px; }
451
506
 
452
507
  .dcAgentWbActions {
453
508
  display: flex;
@@ -460,10 +515,10 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
460
515
  .dcAgentQccBadge {
461
516
  flex: 0 0 auto;
462
517
  padding: 4px 10px;
463
- border: 1px solid light-dark(#e4e8f0, #303947);
518
+ border: 1px solid var(--dc-border);
464
519
  border-radius: 999px;
465
- color: light-dark(#697386, #aab5c7);
466
- font-size: 11px;
520
+ color: var(--dc-muted);
521
+ font-size: 12px;
467
522
  white-space: nowrap;
468
523
  }
469
524
 
@@ -473,42 +528,75 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
473
528
  height: 30px;
474
529
  display: grid;
475
530
  place-items: center;
476
- border: 1px solid light-dark(#e4e8f0, #303947);
531
+ border: 1px solid var(--dc-border);
477
532
  border-radius: 8px;
478
533
  background: transparent;
479
534
  color: inherit;
480
535
  font-size: 15px;
481
536
  cursor: pointer;
482
537
  }
483
- .dcAgentWbClose:hover, .dcAgentWbClose:focus-visible { background: light-dark(#f6f8fb, #202733); }
538
+ .dcAgentWbClose:hover, .dcAgentWbClose:focus-visible { background: var(--dc-page); }
484
539
 
485
540
  .dcAgentStepper {
486
541
  display: grid;
487
- grid-template-columns: repeat(4, minmax(0, 1fr));
488
- gap: 8px;
489
- padding: 12px 18px;
490
- border-bottom: 1px solid light-dark(#e4e8f0, #303947);
491
- background: light-dark(#fbfcfe, #12171e);
542
+ grid-template-columns: repeat(var(--dc-stage-count, 5), minmax(0, 1fr));
543
+ min-width: 0;
544
+ border-bottom: 1px solid var(--dc-border);
545
+ background: var(--dc-surface);
492
546
  }
493
547
 
494
548
  .dcAgentStep {
549
+ position: relative;
550
+ min-width: 0;
495
551
  display: flex;
552
+ flex-direction: column;
496
553
  align-items: center;
497
554
  justify-content: center;
498
- gap: 6px;
499
- padding: 9px 6px;
500
- border: 1px solid light-dark(#e4e8f0, #303947);
501
- border-radius: 9px;
555
+ gap: 8px;
556
+ padding: 12px 4px;
557
+ border: 0;
558
+ border-right: 1px solid var(--dc-border);
559
+ border-radius: 0;
502
560
  background: transparent;
503
- color: light-dark(#697386, #aab5c7);
561
+ color: var(--dc-muted);
504
562
  font-size: 12px;
563
+ font-weight: 600;
505
564
  cursor: pointer;
506
- white-space: nowrap;
507
565
  }
566
+ .dcAgentStep:last-child { border-right: 0; }
567
+ .dcAgentStep:hover { background: var(--dc-page); }
508
568
  .dcAgentStep.is-active {
509
- color: light-dark(#1556cf, #8cb3ff);
510
- border-color: light-dark(#2869e6, #6d9eff);
511
- background: light-dark(#edf4ff, #172841);
569
+ color: var(--dc-action);
570
+ background: var(--dc-selected);
571
+ }
572
+ .dcAgentStep.is-active::after {
573
+ content: '';
574
+ position: absolute;
575
+ bottom: 0;
576
+ left: 8px;
577
+ right: 8px;
578
+ height: 3px;
579
+ border-radius: 3px 3px 0 0;
580
+ background: var(--dc-action);
581
+ }
582
+ .dcAgentStepIcon {
583
+ display: grid;
584
+ place-items: center;
585
+ width: 30px;
586
+ height: 30px;
587
+ flex: none;
588
+ border: 1px solid var(--dc-border);
589
+ border-radius: 8px;
590
+ }
591
+ .dcAgentStepIcon svg { display: block; }
592
+ .dcAgentStepLabel {
593
+ display: block;
594
+ width: 100%;
595
+ min-width: 0;
596
+ line-height: 18px;
597
+ white-space: nowrap;
598
+ overflow: hidden;
599
+ text-overflow: ellipsis;
512
600
  }
513
601
 
514
602
  .dcAgentWbBody {
@@ -518,16 +606,16 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
518
606
  }
519
607
 
520
608
  .dcAgentPane { display: flex; flex-direction: column; gap: 14px; }
521
- .dcAgentHint { margin: 0; color: light-dark(#697386, #aab5c7); font-size: 13px; line-height: 1.6; }
609
+ .dcAgentHint { margin: 0; color: var(--dc-muted); font-size: 13px; line-height: 1.6; }
522
610
 
523
611
  .dcAgentTextarea {
524
612
  width: 100%;
525
613
  box-sizing: border-box;
526
614
  min-height: 132px;
527
615
  padding: 12px;
528
- border: 1px solid light-dark(#cfd6e2, #485364);
529
- border-radius: 10px;
530
- background: light-dark(#ffffff, #191f28);
616
+ border: 1px solid var(--dc-border);
617
+ border-radius: 8px;
618
+ background: var(--dc-surface);
531
619
  color: inherit;
532
620
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
533
621
  font-size: 12px;
@@ -540,29 +628,29 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
540
628
  box-sizing: border-box;
541
629
  min-width: 0;
542
630
  padding: 8px 12px;
543
- border: 1px solid light-dark(#cfd6e2, #485364);
544
- border-radius: 9px;
631
+ border: 1px solid var(--dc-border);
632
+ border-radius: 6px;
545
633
  font-size: 12px;
546
- background: light-dark(#ffffff, #191f28);
634
+ background: var(--dc-surface);
547
635
  color: inherit;
548
636
  }
549
637
 
550
638
  .dcAgentButton {
551
639
  padding: 9px 16px;
552
- border: 1px solid light-dark(#cfd6e2, #485364);
553
- border-radius: 9px;
554
- background: light-dark(#ffffff, #191f28);
640
+ border: 1px solid var(--dc-border);
641
+ border-radius: 6px;
642
+ background: var(--dc-surface);
555
643
  color: inherit;
556
644
  font-size: 13px;
557
645
  cursor: pointer;
558
646
  }
559
- .dcAgentButton:hover, .dcAgentButton:focus-visible { border-color: light-dark(#2869e6, #6d9eff); }
647
+ .dcAgentButton:hover, .dcAgentButton:focus-visible { border-color: var(--dc-action); }
560
648
  .dcAgentButton.is-primary {
561
649
  border-color: transparent;
562
- color: #ffffff;
563
- background: light-dark(#2869e6, #3d7bf0);
650
+ color: var(--dc-on-action);
651
+ background: var(--dc-action);
564
652
  }
565
- .dcAgentButton.is-primary:hover, .dcAgentButton.is-primary:focus-visible { background: light-dark(#1556cf, #6d9eff); }
653
+ .dcAgentButton.is-primary:hover, .dcAgentButton.is-primary:focus-visible { background: var(--dc-hover); }
566
654
  .dcAgentButton:disabled { opacity: 0.5; cursor: not-allowed; }
567
655
 
568
656
  .dcAgentGrid {
@@ -573,14 +661,14 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
573
661
 
574
662
  .dcAgentCard {
575
663
  padding: 12px 14px;
576
- border: 1px solid light-dark(#e4e8f0, #303947);
577
- border-radius: 11px;
578
- background: light-dark(#fbfcfe, #191f28);
664
+ border: 1px solid var(--dc-border);
665
+ border-radius: 8px;
666
+ background: var(--dc-page);
579
667
  }
580
- .dcAgentCard span { display: block; color: light-dark(#697386, #aab5c7); font-size: 11px; }
668
+ .dcAgentCard span { display: block; color: var(--dc-muted); font-size: 12px; }
581
669
  .dcAgentCard b { display: block; margin-top: 3px; font-size: 18px; }
582
- .dcAgentCard b.is-good { color: light-dark(#118a5b, #56d39b); }
583
- .dcAgentCard b.is-warn { color: light-dark(#c17412, #f4b85d); }
670
+ .dcAgentCard b.is-good { color: var(--dc-success); }
671
+ .dcAgentCard b.is-warn { color: var(--dc-review); }
584
672
  .dcAgentCard b.is-bad { color: light-dark(#d2454f, #ff838b); }
585
673
 
586
674
  .dcAgentTable {
@@ -591,9 +679,9 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
591
679
  .dcAgentTable th, .dcAgentTable td {
592
680
  padding: 7px 9px;
593
681
  text-align: left;
594
- border-bottom: 1px solid light-dark(#eef1f6, #242b36);
682
+ border-bottom: 1px solid var(--dc-border);
595
683
  }
596
- .dcAgentTable th { color: light-dark(#697386, #aab5c7); font-weight: 600; }
684
+ .dcAgentTable th { color: var(--dc-muted); font-weight: 600; }
597
685
  .dcAgentTable td.num { font-variant-numeric: tabular-nums; }
598
686
  .dcAgentTableWrap { max-width: 100%; overflow-x: auto; }
599
687
  .dcAgentTableWrap .dcAgentTable { min-width: 720px; table-layout: auto; }
@@ -605,7 +693,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
605
693
  .dcAgentError {
606
694
  padding: 10px 12px;
607
695
  border: 1px solid light-dark(#ffd6d8, #5b2f33);
608
- border-radius: 9px;
696
+ border-radius: 6px;
609
697
  background: light-dark(#fff0f0, #351d21);
610
698
  color: light-dark(#d2454f, #ff838b);
611
699
  font-size: 12px;
@@ -614,22 +702,22 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
614
702
  .dcAgentChips { display: flex; flex-wrap: wrap; gap: 6px; }
615
703
  .dcAgentChip {
616
704
  padding: 4px 10px;
617
- border: 1px solid light-dark(#e4e8f0, #303947);
705
+ border: 1px solid var(--dc-border);
618
706
  border-radius: 999px;
619
- font-size: 11px;
620
- color: light-dark(#697386, #aab5c7);
707
+ font-size: 12px;
708
+ color: var(--dc-muted);
621
709
  }
622
710
  .dcAgentChip.is-selected {
623
- color: light-dark(#1556cf, #8cb3ff);
624
- border-color: light-dark(#2869e6, #6d9eff);
625
- background: light-dark(#edf4ff, #172841);
711
+ color: var(--dc-action);
712
+ border-color: var(--dc-action);
713
+ background: var(--dc-selected);
626
714
  }
627
715
  .dcAgentCheck { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; }
628
716
  .dcAgentSection {
629
717
  padding: 14px;
630
- border: 1px solid light-dark(#e4e8f0, #303947);
631
- border-radius: 11px;
632
- background: light-dark(#fbfcfe, #191f28);
718
+ border: 1px solid var(--dc-border);
719
+ border-radius: 8px;
720
+ background: var(--dc-page);
633
721
  }
634
722
  .dcAgentSection h3 { margin: 0 0 8px; font-size: 13px; }
635
723
  .dcAgentCandidate {
@@ -638,32 +726,32 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
638
726
  gap: 10px;
639
727
  align-items: center;
640
728
  padding: 10px 0;
641
- border-bottom: 1px solid light-dark(#eef1f6, #242b36);
729
+ border-bottom: 1px solid var(--dc-border);
642
730
  }
643
731
  .dcAgentCandidate:last-child { border-bottom: 0; }
644
- .dcAgentCandidate small { color: light-dark(#697386, #aab5c7); }
732
+ .dcAgentCandidate small { color: var(--dc-muted); }
645
733
  .dcAgentProgress { height: 8px; overflow: hidden; border-radius: 99px; background: light-dark(#e8edf5, #293240); }
646
- .dcAgentProgress > span { display: block; height: 100%; background: #2869e6; }
734
+ .dcAgentProgress > span { display: block; height: 100%; background: var(--dc-action); }
647
735
 
648
736
  /* M3 · overlay 头部 jobs 状态 pill(轮询 /mvp/jobs,不接计费遥测)。 */
649
737
  .dcAgentJobsPill {
650
738
  flex: 0 0 auto;
651
739
  padding: 4px 10px;
652
- border: 1px solid light-dark(#e4e8f0, #303947);
740
+ border: 1px solid var(--dc-border);
653
741
  border-radius: 999px;
654
- font-size: 11px;
742
+ font-size: 12px;
655
743
  white-space: nowrap;
656
- color: light-dark(#697386, #aab5c7);
744
+ color: var(--dc-muted);
657
745
  }
658
746
  .dcAgentJobsPill[data-state='running'] {
659
- color: light-dark(#1556cf, #8cb3ff);
660
- border-color: light-dark(#2869e6, #6d9eff);
661
- background: light-dark(#edf4ff, #172841);
747
+ color: var(--dc-action);
748
+ border-color: var(--dc-action);
749
+ background: var(--dc-selected);
662
750
  }
663
751
  .dcAgentJobsPill[data-state='completed'] {
664
- color: light-dark(#118a5b, #56d39b);
665
- border-color: light-dark(#118a5b, #2f7d5e);
666
- background: light-dark(#eefaf3, #12261d);
752
+ color: var(--dc-success);
753
+ border-color: var(--dc-success);
754
+ background: var(--dc-success-bg);
667
755
  }
668
756
  .dcAgentJobsPill[data-state='failed'] {
669
757
  color: light-dark(#d2454f, #ff838b);
@@ -677,9 +765,9 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
677
765
  flex-direction: column;
678
766
  gap: 8px;
679
767
  padding: 12px 14px;
680
- border: 1px solid light-dark(#e4e8f0, #303947);
681
- border-radius: 11px;
682
- background: light-dark(#fbfcfe, #191f28);
768
+ border: 1px solid var(--dc-border);
769
+ border-radius: 8px;
770
+ background: var(--dc-page);
683
771
  margin: 4px 0;
684
772
  }
685
773
  .dcAgentToolCardHead {
@@ -699,34 +787,34 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
699
787
  flex: 0 0 auto;
700
788
  padding: 1px 8px;
701
789
  border-radius: 999px;
702
- font-size: 11px;
703
- color: light-dark(#697386, #aab5c7);
704
- border: 1px solid light-dark(#e4e8f0, #303947);
790
+ font-size: 12px;
791
+ color: var(--dc-muted);
792
+ border: 1px solid var(--dc-border);
705
793
  }
706
- .dcAgentToolCardState.is-ok { color: light-dark(#118a5b, #56d39b); }
794
+ .dcAgentToolCardState.is-ok { color: var(--dc-success); }
707
795
  .dcAgentToolCardState.is-error { color: light-dark(#d2454f, #ff838b); }
708
- .dcAgentToolCardState.is-running { color: light-dark(#1556cf, #8cb3ff); }
709
- .dcAgentToolCardState.is-stopped { color: light-dark(#697386, #aab5c7); }
796
+ .dcAgentToolCardState.is-running { color: var(--dc-action); }
797
+ .dcAgentToolCardState.is-stopped { color: var(--dc-muted); }
710
798
  .dcAgentToolCardBody {
711
799
  margin: 0;
712
800
  white-space: pre-wrap;
713
801
  word-break: break-word;
714
802
  font-size: 12px;
715
803
  line-height: 1.6;
716
- color: light-dark(#33415a, #c9d4e5);
804
+ color: var(--dc-text);
717
805
  }
718
- .dcAgentHistoryTask { border: 1px solid light-dark(#dce4f1, #344052); border-radius: 9px; background: light-dark(#fff, #1b222e); color: inherit; font: inherit; cursor: pointer; }
806
+ .dcAgentHistoryTask { border: 1px solid var(--dc-border); border-radius: 6px; background: var(--dc-surface); color: inherit; font: inherit; cursor: pointer; }
719
807
  .dcAgentWizardNav { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; margin-bottom: 12px; }
720
- .dcAgentWizardStep { display: flex; align-items: center; gap: 6px; padding: 7px; border: 1px solid light-dark(#d9dee8, #394352); border-radius: 9px; background: transparent; color: inherit; font: inherit; font-size: 11px; cursor: pointer; }
721
- .dcAgentWizardStep b { display: grid; place-items: center; width: 20px; height: 20px; border-radius: 50%; background: light-dark(#eef1f6, #252e3b); color: light-dark(#607088, #b9c6da); }
722
- .dcAgentWizardStep.is-active { border-color: #2869e6; background: light-dark(#edf4ff, #172841); color: light-dark(#1556cf, #8cb3ff); }
723
- .dcAgentWizardStep.is-active b { background: #2869e6; color: white; }
808
+ .dcAgentWizardStep { display: flex; align-items: center; gap: 6px; padding: 7px; border: 1px solid var(--dc-border); border-radius: 6px; background: transparent; color: inherit; font: inherit; font-size: 12px; cursor: pointer; }
809
+ .dcAgentWizardStep b { display: grid; place-items: center; width: 20px; height: 20px; border-radius: 50%; background: var(--dc-border); color: var(--dc-muted); }
810
+ .dcAgentWizardStep.is-active { border-color: var(--dc-action); background: var(--dc-selected); color: var(--dc-action); }
811
+ .dcAgentWizardStep.is-active b { background: var(--dc-action); color: var(--dc-on-action); }
724
812
  .dcAgentWizardPane { min-height: 230px; }
725
813
  .dcAgentWizardPane h4 { margin: 0 0 3px; font-size: 14px; }
726
- .dcAgentWizardPane > p { margin: 0 0 12px; color: light-dark(#697386, #aab5c7); font-size: 11px; line-height: 17px; }
814
+ .dcAgentWizardPane > p { margin: 0 0 12px; color: var(--dc-muted); font-size: 12px; line-height: 17px; }
727
815
  .dcAgentPromptRules { display: grid; gap: 8px; margin-top: 14px; }
728
816
  .dcAgentPromptRules label { font-size: 12px; }
729
- .dcAgentPromptPreview { max-height: 260px; overflow: auto; margin: 10px 0 0; padding: 12px; border-radius: 10px; background: light-dark(#f6f8fb, #11171f); white-space: pre-wrap; word-break: break-word; font: inherit; font-size: 11px; line-height: 18px; }
817
+ .dcAgentPromptPreview { max-height: 260px; overflow: auto; margin: 10px 0 0; padding: 12px; border-radius: 8px; background: var(--dc-page); white-space: pre-wrap; word-break: break-word; font: inherit; font-size: 12px; line-height: 18px; }
730
818
  .dcAgentFormField { display: grid; gap: 6px; font-size: 12px; font-weight: 600; }
731
819
  .dcAgentMappingRow { display: grid; grid-template-columns: minmax(0, 1fr) 24px minmax(180px, 1fr); align-items: center; gap: 8px; margin-top: 7px; font-size: 12px; }
732
820
  .dcAgentMappingRow > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@@ -742,13 +830,13 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
742
830
  border: 0;
743
831
  border-radius: 6px;
744
832
  background: transparent;
745
- color: light-dark(#2869e6, #8cb3ff);
833
+ color: var(--dc-action);
746
834
  font: inherit;
747
- font-size: 11px;
835
+ font-size: 12px;
748
836
  cursor: pointer;
749
837
  }
750
- .dcAgentFieldAction:hover, .dcAgentFieldAction:focus-visible { background: light-dark(#edf4ff, #172841); }
751
- .dcAgentPreviewTable { margin-top: 12px; overflow: auto; border: 1px solid light-dark(#e4e8f0, #303947); border-radius: 10px; }
838
+ .dcAgentFieldAction:hover, .dcAgentFieldAction:focus-visible { background: var(--dc-selected); }
839
+ .dcAgentPreviewTable { margin-top: 12px; overflow: auto; border: 1px solid var(--dc-border); border-radius: 8px; }
752
840
  .dcAgentHistoryTask { display: block; width: 100%; padding: 10px; text-align: left; }
753
841
  .dcAgentHistoryTask h3 { margin: 0; font-size: 12px; }
754
842
  /*
@@ -777,7 +865,6 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
777
865
  @media (max-width: 760px) {
778
866
  .dcAgentWorkbench, .dcAgentWorkbench.is-expanded { width: 100vw; max-width: none; min-width: 0; border-radius: 0; }
779
867
  .dcAgentOverlay { background: rgba(8, 10, 14, 0.22); pointer-events: auto; }
780
- .dcAgentStepper { grid-template-columns: repeat(2, minmax(0, 1fr)); }
781
868
  .dcAgentQccBadge, .dcAgentJobsPill { display: none; }
782
869
  .dcAgentCandidate { grid-template-columns: 1fr; }
783
870
  .dcAgentCapabilities { justify-content: flex-start; padding-inline: 12px; }
@@ -793,6 +880,40 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
793
880
  .dcAgentWorkbench { width: 420px; max-width: 48vw; min-width: 360px; }
794
881
  .dcAgentQccBadge, .dcAgentJobsPill { display: none; }
795
882
  }
883
+ @media (max-width: 360px) {
884
+ .dcAgentStep { font-size: 11px; padding: 10px 3px; gap: 6px; }
885
+ .dcAgentStepIcon { width: 26px; height: 26px; }
886
+ .dcAgentStepIcon svg { width: 18px; height: 18px; }
887
+ }
888
+ /* Distinct levels: management tabs → compact task steps → working content. */
889
+ .dcAgentWorkbench, .dcAgentPromptPanel { font-size: 14px; line-height: 1.5; }
890
+ .dcAgentWbHeader, .dcAgentManagement, .dcAgentStepper { flex: none; }
891
+ .dcAgentManagement { display: flex; gap: 24px; padding: 0 18px; border-bottom: 1px solid var(--dc-border); }
892
+ .dcAgentManagement .dcAgentButton { border: 0; border-bottom: 3px solid transparent; border-radius: 0; padding: 10px 0; background: transparent; }
893
+ .dcAgentManagement .dcAgentButton[aria-pressed="true"] { border-bottom-color: var(--dc-action); color: var(--dc-action); font-weight: 600; }
894
+ .dcAgentCapability { border-radius: 8px; }
895
+ .dcAgentWbBody { min-height: 0; }
896
+ .dcAgentTable th { background: var(--dc-table-head); color: var(--dc-text); }
897
+ .dcAgentTable th, .dcAgentTable td { height: 44px; box-sizing: border-box; font-size: 13px; }
898
+ .dcAgentTable tbody tr:hover { background: var(--dc-selected); }
899
+ .dcAgentSection, .dcAgentCard { background: var(--dc-surface); }
900
+ .dcAgentFieldGroup { background: var(--dc-page); padding: 12px; border-radius: 8px; }
901
+ .dcAgentPromptFieldGrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 8px; margin-top: 10px; }
902
+ .dcAgentPromptFieldGrid .dcAgentPromptChoice { border: 0; border-radius: 4px; min-width: 0; align-items: flex-start; font-size: 13px; }
903
+ .dcAgentFieldGroup .dcAgentChips { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
904
+ .dcAgentFieldGroup .dcAgentChip { border-radius: 4px; }
905
+ .dcAgentPromptText, .dcAgentTextarea, .dcAgentField { font-size: 14px; }
906
+ .dcAgentPromptTrigger { border-radius: 6px; }
907
+ .dcAgentPromptAction.is-primary:hover:not(:disabled) { background: var(--dc-hover); }
908
+ :is(.dcAgentWorkbench, .dcAgentPromptPanel, .dcAgentCapabilities, .dcAgentPromptLayer) :is(button, input, select, textarea, summary):focus-visible,
909
+ .dcAgentLauncher:focus-visible { outline: 2px solid var(--dc-action); outline-offset: 2px; }
910
+ @media (max-width: 760px) {
911
+ [data-dc-agent-hero-title="true"] { font-size: 20px; }
912
+ .dcAgentHeroLogo { width: 40px; height: 40px; border-radius: 8px; }
913
+ .dcAgentPromptText, .dcAgentTextarea, .dcAgentField { font-size: 16px; }
914
+ .dcAgentPromptFieldGrid { grid-template-columns: 1fr; }
915
+ }
916
+
796
917
  `;
797
918
 
798
919
  /** 安装入口、会话能力按钮与右侧工作台样式。 */
@@ -840,18 +961,18 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
840
961
  }
841
962
 
842
963
  const STEPS = [
843
- { key: 'upload', label: '导入与核验', icon: '1' },
844
- { key: 'rules', label: '规则与体检', icon: '2' },
845
- { key: 'match', label: '主体匹配', icon: '3' },
846
- { key: 'enrich', label: '字段补全', icon: '4' },
847
- { key: 'download', label: '结果下载', icon: '5' },
964
+ { key: 'upload', label: '导入与核验', icon: 'upload' },
965
+ { key: 'rules', label: '规则与体检', icon: 'check' },
966
+ { key: 'match', label: '主体匹配', icon: 'search' },
967
+ { key: 'enrich', label: '字段补全', icon: 'database' },
968
+ { key: 'download', label: '结果下载', icon: 'table' },
848
969
  ];
849
970
 
850
971
  const CAPABILITIES = [
851
972
  { key: 'upload', label: '导入名单', icon: IconPaperclipOutline16, fallback: '+' },
852
973
  { key: 'profile', label: '质量体检', icon: IconChecklistOutline14, fallback: '✓' },
853
974
  { key: 'match', label: '匹配核验', icon: IconSearchOutline16, fallback: '⌕' },
854
- { key: 'enrich', label: '字段补全', icon: IconDataOutline16, fallback: '▦' },
975
+ { key: 'enrich', label: '字段补全', icon: DatabaseLogo, fallback: '▦' },
855
976
  { key: 'history', label: '任务历史', icon: IconArchiveOutline20, fallback: '◷' },
856
977
  ];
857
978
 
@@ -1735,7 +1856,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
1735
1856
  console.error('[dc-agent] open failed:', error);
1736
1857
  }
1737
1858
  },
1738
- children: wide ? '🧹 数据清洗补全' : '🧹',
1859
+ children: h('span', { className: 'dcAgentLauncherContent' }, h(DatabaseLogo), wide ? h('span', null, '数据清洗补全') : null),
1739
1860
  });
1740
1861
  if (!topMount || typeof reactDom.createPortal !== 'function') return launcher;
1741
1862
  return reactDom.createPortal(h('div', {
@@ -1889,6 +2010,9 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
1889
2010
  if (!hero) return () => {};
1890
2011
  const changedTitles = new Map();
1891
2012
  const changedBadges = new Map();
2013
+ const changedMarks = new Map();
2014
+ const changedRows = new Map();
2015
+ const ownedLogos = new Map();
1892
2016
  const hiddenForeignDocks = new Map();
1893
2017
  const composerStack = marker?.parentElement?.parentElement;
1894
2018
  // 单一会话所有权由入口的 enabled 参数(useCleaningSession(sessionId) && composerPhase==='blank')
@@ -1910,6 +2034,29 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
1910
2034
  if (!changedTitles.has(title)) changedTitles.set(title, title.textContent ?? '');
1911
2035
  title.dataset.dcAgentHeroTitle = 'true';
1912
2036
  if (title.textContent !== '数据清洗补全智能体') { title.textContent = '数据清洗补全智能体'; mutated = true; }
2037
+ // 只适配本会话已确认的 DSH headline;未知宿主结构保留原状。
2038
+ const row = title.parentElement;
2039
+ const nativeMark = row?.querySelector?.('[class*="fishHitbox"]');
2040
+ if (nativeMark && typeof document.createElementNS === 'function') {
2041
+ if (!changedRows.has(row)) changedRows.set(row, row.getAttribute('data-dc-agent-hero-row'));
2042
+ row.setAttribute('data-dc-agent-hero-row', 'true');
2043
+ if (!changedMarks.has(nativeMark)) changedMarks.set(nativeMark, nativeMark.style.display);
2044
+ nativeMark.style.display = 'none';
2045
+ if (!ownedLogos.get(row)?.isConnected) {
2046
+ const logo = document.createElement('span');
2047
+ logo.className = 'dcAgentHeroLogo';
2048
+ logo.setAttribute('aria-hidden', 'true');
2049
+ const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
2050
+ for (const [name, value] of Object.entries({ viewBox: '0 0 24 24', width: '26', height: '26', fill: 'none', stroke: 'currentColor', 'stroke-width': '1.7', 'stroke-linecap': 'round', 'stroke-linejoin': 'round', focusable: 'false' })) svg.setAttribute(name, value);
2051
+ const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
2052
+ path.setAttribute('d', DATABASE_PATH);
2053
+ svg.appendChild(path);
2054
+ logo.appendChild(svg);
2055
+ row.insertBefore(logo, title);
2056
+ ownedLogos.set(row, logo);
2057
+ mutated = true;
2058
+ }
2059
+ }
1913
2060
  }
1914
2061
  if (badge) {
1915
2062
  if (!changedBadges.has(badge)) changedBadges.set(badge, badge.style?.display ?? '');
@@ -1947,6 +2094,12 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
1947
2094
  observer?.observe?.(hero, { childList: true, subtree: true });
1948
2095
  return () => {
1949
2096
  observer?.disconnect?.();
2097
+ for (const logo of ownedLogos.values()) logo.remove();
2098
+ for (const [mark, originalDisplay] of changedMarks) mark.style.display = originalDisplay;
2099
+ for (const [row, originalValue] of changedRows) {
2100
+ if (originalValue === null) row.removeAttribute('data-dc-agent-hero-row');
2101
+ else row.setAttribute('data-dc-agent-hero-row', originalValue);
2102
+ }
1950
2103
  for (const [title, originalText] of changedTitles) {
1951
2104
  if (title.textContent === '数据清洗补全智能体') title.textContent = originalText;
1952
2105
  delete title.dataset.dcAgentHeroTitle;
@@ -2064,6 +2217,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
2064
2217
  const [imageLightbox, setImageLightbox] = react.useState(false);
2065
2218
  const [cleaningKeys, setCleaningKeys] = react.useState(DEFAULT_CLEANING_KEYS);
2066
2219
  const [enrichmentKeys, setEnrichmentKeys] = react.useState(DEFAULT_ENRICHMENT_KEYS);
2220
+ const [fieldQuery, setFieldQuery] = react.useState('');
2067
2221
  const [anchorKeys, setAnchorKeys] = react.useState(['company_name', 'credit_no']);
2068
2222
  const [matchRules, setPromptMatchRules] = react.useState({
2069
2223
  normalizeNames: true,
@@ -2501,18 +2655,27 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
2501
2655
  h('b', null, '清洗目标'),
2502
2656
  h('div', { className: 'dcAgentPromptChoices' }, choice(CLEANING_OPTIONS, cleaningKeys, setCleaningKeys)),
2503
2657
  ),
2504
- FIELD_GROUPS.map(([groupId, label, fields, sourceTool]) => h('div', { className: 'dcAgentPromptGroup', key: groupId },
2658
+ h('label', { className: 'dcAgentPromptField' },
2659
+ h('span', null, `查找补全字段 · 已选 ${enrichmentKeys.length}`),
2660
+ h('input', { type: 'search', className: 'dcAgentField', value: fieldQuery, 'aria-label': '查找补全字段',
2661
+ placeholder: '搜索维度、字段或工具名称', onChange: (event) => setFieldQuery(event.target.value) })),
2662
+ !FIELD_GROUPS.some((group) => visibleCatalogFields(group, fieldQuery).length) ? h('p', { className: 'dcAgentHint', role: 'status' }, '没有匹配的字段;已选字段保持不变。') : null,
2663
+ FIELD_GROUPS.filter((group) => visibleCatalogFields(group, fieldQuery).length).map(([groupId, label, fields, sourceTool]) => h('div', { className: 'dcAgentPromptGroup dcAgentFieldGroup', key: groupId },
2505
2664
  h('div', { className: 'dcAgentFieldGroupHead' },
2506
2665
  h('div', null,
2507
2666
  h('b', null, `${label} · ${fields.filter(([id]) => enrichmentKeys.includes(id)).length}/${fields.length}`),
2508
2667
  sourceTool ? h('small', { className: 'dcAgentHint' }, `来源:${sourceTool}`) : null,
2509
2668
  ),
2510
2669
  h('div', { className: 'dcAgentFieldGroupActions' },
2511
- h('button', { type: 'button', className: 'dcAgentFieldAction', onClick: () => setPromptFieldGroup(fields, true) }, '全选'),
2512
- h('button', { type: 'button', className: 'dcAgentFieldAction', onClick: () => setPromptFieldGroup(fields, false) }, '清空'),
2670
+ h('button', { type: 'button', className: 'dcAgentFieldAction', title: '选中本维度全部字段,不受搜索过滤影响', onClick: () => setPromptFieldGroup(fields, true) }, '全选'),
2671
+ h('button', { type: 'button', className: 'dcAgentFieldAction', title: '清空本维度全部字段,不受搜索过滤影响', onClick: () => setPromptFieldGroup(fields, false) }, '清空'),
2513
2672
  ),
2514
2673
  ),
2515
- h('div', { className: 'dcAgentPromptChoices' }, choice(fields, enrichmentKeys, setEnrichmentKeys)),
2674
+ h('div', { className: 'dcAgentPromptFieldGrid' }, visibleCatalogFields([groupId, label, fields, sourceTool], fieldQuery).map(([id, fieldLabel]) => h('label', {
2675
+ key: id, className: `dcAgentPromptChoice${enrichmentKeys.includes(id) ? ' is-selected' : ''}`,
2676
+ }, h('input', { type: 'checkbox', checked: enrichmentKeys.includes(id),
2677
+ onChange: (event) => setEnrichmentKeys((current) => event.target.checked ? [...new Set([...current, id])] : current.filter((key) => key !== id)),
2678
+ }), fieldLabel))),
2516
2679
  )),
2517
2680
  ) : null,
2518
2681
  wizardStep === 4 ? h('div', { className: 'dcAgentWizardPane' },
@@ -2553,9 +2716,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
2553
2716
  title: '打开数据清洗补全工作台',
2554
2717
  onClick: () => requestWorkbenchOpen(null, sessionId),
2555
2718
  },
2556
- typeof IconDataOutline16 === 'function'
2557
- ? h(IconDataOutline16, { size: 16, 'aria-hidden': 'true' })
2558
- : h('span', { 'aria-hidden': 'true' }, '▦'),
2719
+ h(DatabaseLogo, { size: 16 }),
2559
2720
  h('span', null, '清洗补全工作台'),
2560
2721
  );
2561
2722
  }
@@ -2830,6 +2991,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
2830
2991
  const paidConfirmed = useStore((state) => state.paidConfirmed);
2831
2992
  const jobs = useStore((state) => state.jobs);
2832
2993
  const activeSessionId = useStore((state) => state.activeSessionId);
2994
+ const [fieldQuery, setFieldQuery] = react.useState('');
2833
2995
 
2834
2996
  react.useEffect(() => {
2835
2997
  rootWorkbenchActions = actions;
@@ -3576,18 +3738,22 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
3576
3738
  h('span', { className: 'dcAgentChip' }, '第一批 40'),
3577
3739
  h('span', { className: 'dcAgentChip' }, '第二批 58'),
3578
3740
  ),
3579
- uiFieldGroups.map(([groupId, label, fields, sourceTool]) => h('div', { key: groupId, className: 'dcAgentFieldGroup' },
3741
+ h('label', { className: 'dcAgentPromptField' }, h('span', null, '查找补全字段'),
3742
+ h('input', { type: 'search', className: 'dcAgentField', value: fieldQuery, 'aria-label': '查找补全字段',
3743
+ placeholder: '搜索维度、字段或工具名称', onChange: (event) => setFieldQuery(event.target.value) })),
3744
+ !uiFieldGroups.some((group) => visibleCatalogFields(group, fieldQuery).length) ? h('p', { className: 'dcAgentHint', role: 'status' }, '没有匹配的字段;已选字段保持不变。') : null,
3745
+ uiFieldGroups.filter((group) => visibleCatalogFields(group, fieldQuery).length).map(([groupId, label, fields, sourceTool]) => h('div', { key: groupId, className: 'dcAgentFieldGroup' },
3580
3746
  h('div', { className: 'dcAgentFieldGroupHead' },
3581
3747
  h('div', null,
3582
3748
  h('b', null, `${label} · ${fields.filter(([id]) => fieldSelection.includes(id)).length}/${fields.length}`),
3583
3749
  sourceTool ? h('small', { className: 'dcAgentHint' }, `来源:${sourceTool}`) : null,
3584
3750
  ),
3585
3751
  h('div', { className: 'dcAgentFieldGroupActions' },
3586
- h('button', { type: 'button', className: 'dcAgentFieldAction', onClick: () => setWorkbenchFieldGroup(fields, true) }, '全选'),
3587
- h('button', { type: 'button', className: 'dcAgentFieldAction', onClick: () => setWorkbenchFieldGroup(fields, false) }, '清空'),
3752
+ h('button', { type: 'button', className: 'dcAgentFieldAction', title: '选中本维度全部字段,不受搜索过滤影响', onClick: () => setWorkbenchFieldGroup(fields, true) }, '全选'),
3753
+ h('button', { type: 'button', className: 'dcAgentFieldAction', title: '清空本维度全部字段,不受搜索过滤影响', onClick: () => setWorkbenchFieldGroup(fields, false) }, '清空'),
3588
3754
  ),
3589
3755
  ),
3590
- h('div', { className: 'dcAgentChips' }, fields.map(([key, fieldLabel]) => h('label', { key, className: `dcAgentChip${fieldSelection.includes(key) ? ' is-selected' : ''}` },
3756
+ h('div', { className: 'dcAgentChips' }, visibleCatalogFields([groupId, label, fields, sourceTool], fieldQuery).map(([key, fieldLabel]) => h('label', { key, className: `dcAgentChip${fieldSelection.includes(key) ? ' is-selected' : ''}` },
3591
3757
  h('input', { type: 'checkbox', checked: fieldSelection.includes(key), onChange: () => actions.toggleField(key) }), ` ${fieldLabel}`,
3592
3758
  ))),
3593
3759
  )),
@@ -3823,7 +3989,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
3823
3989
  },
3824
3990
  h('header', { className: 'dcAgentWbHeader' },
3825
3991
  h('div', { className: 'dcAgentWbTitle' },
3826
- h('span', { className: 'dcAgentWbIcon', 'aria-hidden': 'true' }, '🧹'),
3992
+ h('span', { className: 'dcAgentWbIcon', 'aria-hidden': 'true' }, h(DatabaseLogo, { size: 22 })),
3827
3993
  h('div', null,
3828
3994
  h('b', null, '数据清洗补全'),
3829
3995
  h('small', null, cachedTask ? `${WORKFLOW_STATE_LABELS[cachedTask.state] || cachedTask.state} · ${cachedTask.id.slice(0, 18)}` : '正在创建 Host taskId…'),
@@ -3853,21 +4019,24 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
3853
4019
  }, '✕'),
3854
4020
  ),
3855
4021
  ),
3856
- h('nav', { className: 'dcAgentRow', style: { padding: '10px 16px' }, 'aria-label': '工作台管理' },
4022
+ h('nav', { className: 'dcAgentManagement', 'aria-label': '工作台管理' },
3857
4023
  h('button', { type: 'button', className: 'dcAgentButton', 'aria-pressed': step !== 'history',
3858
4024
  onClick: () => actions.setStep(cachedTask?.stage || 'upload') }, '当前任务'),
3859
4025
  h('button', { type: 'button', className: 'dcAgentButton', 'aria-pressed': step === 'history',
3860
4026
  onClick: () => actions.setStep('history') }, '任务历史'),
3861
4027
  ),
3862
- step !== 'history' ? h('nav', { className: 'dcAgentStepper', 'aria-label': '清洗流程' },
4028
+ step !== 'history' ? h('nav', { className: 'dcAgentStepper', 'aria-label': '清洗流程',
4029
+ style: { '--dc-stage-count': STEPS.length } },
3863
4030
  STEPS.map((st) => h('button', {
3864
4031
  key: st.key,
3865
4032
  type: 'button',
3866
4033
  className: `dcAgentStep${(step === 'profile' ? 'rules' : step) === st.key ? ' is-active' : ''}`,
3867
4034
  'aria-label': st.label,
4035
+ title: st.label,
3868
4036
  'aria-current': (step === 'profile' ? 'rules' : step) === st.key ? 'step' : undefined,
3869
4037
  onClick: () => actions.setStep(st.key),
3870
- }, `${st.icon} ${st.label}`)),
4038
+ }, h('span', { className: 'dcAgentStepIcon' }, h(StageIcon, { kind: st.icon })),
4039
+ h('span', { className: 'dcAgentStepLabel' }, st.label))),
3871
4040
  ) : null,
3872
4041
  h('div', { className: 'dcAgentWbBody' },
3873
4042
  error ? h('div', { className: 'dcAgentError', role: 'alert' }, error) : null,
@@ -3984,6 +4153,8 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
3984
4153
  exports.inject = inject;
3985
4154
  // 测试用纯函数,不构成 Host / DSH 稳定 API。
3986
4155
  exports.__testing = {
4156
+ DatabaseLogo,
4157
+ visibleCatalogFields,
3987
4158
  installCapabilityMount,
3988
4159
  PromptDialog,
3989
4160
  ProductHome,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-data-cleaning-agent",
3
- "version": "0.8.7",
3
+ "version": "0.8.9",
4
4
  "description": "Clean, complete, and profile enterprise name lists in DeepSeek Harness — a data cleaning & completion agent plugin with local CSV/XLSX/JSON engine and optional Qichacha (QCC) MCP enrichment. Maintained by Qichacha/QCC.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",