dsh-data-cleaning-agent 0.8.7 → 0.8.8

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,17 @@
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.8] - 2026-09-06
6
+
7
+ ### Changed
8
+ - 按共享 DSH-UX-001 v1.1.0 企查查蓝方案调整自有界面,统一浅色/深色颜色令牌、紧凑分区、浅蓝表头和键盘焦点;不更改宿主原生输入框、模型及发送机制。
9
+ - 入口、首页、会话头和工作台采用统一数据库线性图标;首页 LOGO 与名称同排。会话级可恢复 Bridge 不注册全局单例品牌槽位,离开首页恢复宿主标题、图标和预览标识。
10
+ - 当前任务/任务历史使用下划线管理标签,五步流程为横向可滚动紧凑导航;快捷菜单仍在原生输入框外下方。
11
+ - 向导与工作台按维度展示字段勾选网格,支持中文字段/维度/工具名称搜索,搜索不会丢失已选字段。维度全选/清空作用于完整维度,不受搜索过滤影响;128 字段与 Host 工作流不变。
12
+
13
+ ### Tests
14
+ - 增补数据库图标、字段过滤、全局槽位隔离与真实 React/Chromium 同排排版、深浅色按钮、字段选择保持、回填发送和宿主图标恢复检查。具体边界见 `docs/QCC-BLUE-UI-ACCEPTANCE.md`。
15
+
5
16
  ## [0.8.7] - 2026-09-06
6
17
 
7
18
  ### 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.8** (stable release)
6
+
7
+ This release aligns the business UI with QCC blue: a database logo beside the home title, consistent entry/workbench icons, and searchable field groups retaining all 128 fields. 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.8**(正式版本)
6
+
7
+ 本版统一企查查蓝业务界面:数据库 LOGO 与首页名称同排,入口/工作台图标一致;字段支持按维度、名称或工具搜索,保留全部 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,23 @@ 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
+ // 搜索仅改变可见字段,绝不清除已选字段或改变 Host 的字段目录。
67
+ function visibleCatalogFields(group, query) {
68
+ const needle = String(query || '').trim().toLowerCase();
69
+ const [, label, fields, tool] = group;
70
+ if (!needle || `${label} ${tool || ''}`.toLowerCase().includes(needle)) return fields;
71
+ return fields.filter(([id, fieldLabel]) => `${id} ${fieldLabel}`.toLowerCase().includes(needle));
72
+ }
73
+
58
74
  /** 客户端所需服务:与 mcp-connector 对齐(槽位 + 会话/工作区/输入机)。 */
59
75
  const inject = ['slots', 'sessions', 'workspaces', 'conversation'];
60
76
 
@@ -62,6 +78,31 @@ window.__ModuleLoader__.load({
62
78
  const SIDEBAR_WORKSPACES_SELECTOR = '[data-slot="sidebar.workspaces"]';
63
79
  const TOP_MOUNT_SELECTOR = '[data-data-cleaning-top-mount="true"]';
64
80
  const stylesCss = `
81
+ /* QCC-blue candidate tokens from shared DSH-UX-001; never theme the global shell. */
82
+ :where(.dcAgentTopMount, .dcAgentLauncher, .dcAgentExperience, .dcAgentCapabilityMount,
83
+ .dcAgentOverlay, .dcAgentPromptLayer, .dcAgentPromptBackdrop, .dcAgentHeaderAction,
84
+ .dcAgentToolCard, [data-dc-agent-hero-row="true"]) {
85
+ --dc-action: light-dark(#0875d1, #82c3ff);
86
+ --dc-hover: light-dark(#0666b7, #acd7ff);
87
+ --dc-on-action: light-dark(#fff, #101820);
88
+ --dc-selected: light-dark(#e6f4ff, #173449);
89
+ --dc-surface: light-dark(#fff, #18232e);
90
+ --dc-page: light-dark(#f6f8fa, #101820);
91
+ --dc-table-head: light-dark(#f2f9fc, #172c3b);
92
+ --dc-text: light-dark(#202c3b, #e7eef6);
93
+ --dc-muted: light-dark(#626f80, #a2b1c2);
94
+ --dc-border: light-dark(#dce4ec, #344657);
95
+ --dc-success: light-dark(#12805c, #78d8b3);
96
+ --dc-success-bg: light-dark(#edf8f2, #193a30);
97
+ --dc-review: light-dark(#946000, #f3c66c);
98
+ accent-color: var(--dc-action);
99
+ }
100
+ .dcAgentLauncherContent { display: inline-flex; align-items: center; gap: 8px; }
101
+ .dcAgentDatabaseLogo { display: block; flex: none; color: var(--dc-action); }
102
+ [data-dc-agent-hero-row="true"] { display: flex; align-items: center; justify-content: center; gap: 12px; }
103
+ [data-dc-agent-hero-title="true"] { min-width: 0; font-size: 28px; line-height: 1.3; color: var(--dc-text); }
104
+ .dcAgentHeroLogo { width: 48px; height: 48px; border-radius: 12px; background: var(--dc-selected); color: var(--dc-action); display: grid; place-items: center; flex: none; }
105
+
65
106
  .dcAgentTopMount {
66
107
  flex: none;
67
108
  min-width: 0;
@@ -118,10 +159,10 @@ window.__ModuleLoader__.load({
118
159
  max-width: calc(100vw - 420px);
119
160
  min-width: 360px;
120
161
  height: 100vh;
121
- border: 1px solid light-dark(#d5dae4, #2a3038);
162
+ border: 1px solid var(--dc-border);
122
163
  border-radius: 12px 0 0 12px;
123
- background: light-dark(#ffffff, #161b23);
124
- color: light-dark(#172033, #edf2fa);
164
+ background: var(--dc-surface);
165
+ color: var(--dc-text);
125
166
  box-shadow: light-dark(-10px 0 32px rgba(33, 55, 88, .12), -12px 0 40px rgba(0, 0, 0, .32));
126
167
  overflow: hidden;
127
168
  pointer-events: auto;
@@ -130,7 +171,7 @@ window.__ModuleLoader__.load({
130
171
 
131
172
  .dcAgentCapabilities {
132
173
  display: flex;
133
- justify-content: center;
174
+ justify-content: safe center;
134
175
  align-items: center;
135
176
  gap: 8px;
136
177
  width: 100%;
@@ -154,10 +195,10 @@ window.__ModuleLoader__.load({
154
195
  padding: 7px 12px;
155
196
  flex-direction: column;
156
197
  justify-content: center;
157
- border: 1px solid light-dark(#e4e8f0, #303947);
198
+ border: 1px solid var(--dc-border);
158
199
  border-radius: 12px;
159
- background: light-dark(rgba(255,255,255,.86), rgba(22,27,35,.86));
160
- color: light-dark(#5d687a, #aab5c7);
200
+ background: var(--dc-surface);
201
+ color: var(--dc-muted);
161
202
  font: inherit;
162
203
  font-size: 12px;
163
204
  cursor: pointer;
@@ -165,9 +206,9 @@ window.__ModuleLoader__.load({
165
206
  .dcAgentCapability:hover,
166
207
  .dcAgentCapability:focus-visible,
167
208
  .dcAgentCapability.is-active {
168
- border-color: light-dark(#c9d9f8, #365681);
169
- background: light-dark(#edf4ff, #172841);
170
- color: light-dark(#1556cf, #8cb3ff);
209
+ border-color: var(--dc-border);
210
+ background: var(--dc-selected);
211
+ color: var(--dc-action);
171
212
  }
172
213
  .dcAgentCapability svg { flex: 0 0 auto; }
173
214
 
@@ -178,7 +219,7 @@ window.__ModuleLoader__.load({
178
219
  box-sizing: border-box;
179
220
  }
180
221
  .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; }
222
+ .dcAgentHomeSummary { margin: 0 20px 8px; text-align: center; color: var(--dc-muted); font-size: 13px; line-height: 20px; }
182
223
  .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
224
  body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
184
225
 
@@ -199,10 +240,10 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
199
240
  left: 16px;
200
241
  min-height: 28px;
201
242
  padding: 3px 10px;
202
- border: 1px solid light-dark(#c9d9f8, #365681);
243
+ border: 1px solid var(--dc-border);
203
244
  border-radius: 999px;
204
- background: light-dark(#edf4ff, #172841);
205
- color: light-dark(#1556cf, #8cb3ff);
245
+ background: var(--dc-selected);
246
+ color: var(--dc-action);
206
247
  font: inherit;
207
248
  font-size: 12px;
208
249
  cursor: pointer;
@@ -217,16 +258,16 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
217
258
  box-sizing: border-box;
218
259
  overflow: hidden;
219
260
  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);
261
+ border: 1px solid var(--dc-border);
262
+ border-radius: 12px;
263
+ background: var(--dc-surface);
264
+ color: var(--dc-text);
224
265
  box-shadow: light-dark(0 18px 48px rgba(33,55,88,.20), 0 20px 54px rgba(0,0,0,.40));
225
266
  pointer-events: auto;
226
267
  }
227
268
  .dcAgentPromptBody { min-height: 0; overflow: auto; overscroll-behavior: contain; padding: 0 2px; }
228
269
  .dcAgentPromptHead, .dcAgentPromptActions { flex: none; }
229
- .dcAgentPromptActions { border-top: 1px solid light-dark(#e4e8f0, #303947); padding-top: 12px; }
270
+ .dcAgentPromptActions { border-top: 1px solid var(--dc-border); padding-top: 12px; }
230
271
  .dcAgentPromptHead {
231
272
  display: flex;
232
273
  align-items: flex-start;
@@ -235,7 +276,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
235
276
  margin-bottom: 12px;
236
277
  }
237
278
  .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; }
279
+ .dcAgentPromptHead p { margin: 3px 0 0; color: var(--dc-muted); font-size: 12px; line-height: 17px; }
239
280
  .dcAgentPromptClose {
240
281
  width: 28px;
241
282
  height: 28px;
@@ -246,7 +287,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
246
287
  color: inherit;
247
288
  cursor: pointer;
248
289
  }
249
- .dcAgentPromptClose:hover { background: light-dark(#f1f4f8, #222a36); }
290
+ .dcAgentPromptClose:hover { background: var(--dc-page); }
250
291
  .dcAgentPromptTabs { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
251
292
  .dcAgentPromptTab,
252
293
  .dcAgentPromptChoice {
@@ -255,8 +296,8 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
255
296
  gap: 5px;
256
297
  min-height: 32px;
257
298
  padding: 5px 10px;
258
- border: 1px solid light-dark(#d9dee8, #394352);
259
- border-radius: 9px;
299
+ border: 1px solid var(--dc-border);
300
+ border-radius: 6px;
260
301
  background: transparent;
261
302
  color: inherit;
262
303
  font: inherit;
@@ -265,9 +306,9 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
265
306
  }
266
307
  .dcAgentPromptTab.is-active,
267
308
  .dcAgentPromptChoice.is-selected {
268
- border-color: light-dark(#2869e6, #6d9eff);
269
- background: light-dark(#edf4ff, #172841);
270
- color: light-dark(#1556cf, #8cb3ff);
309
+ border-color: var(--dc-action);
310
+ background: var(--dc-selected);
311
+ color: var(--dc-action);
271
312
  }
272
313
  .dcAgentPromptField { display: grid; gap: 6px; margin: 10px 0; }
273
314
  .dcAgentPromptField > span { font-size: 12px; font-weight: 600; }
@@ -277,9 +318,9 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
277
318
  min-height: 104px;
278
319
  resize: vertical;
279
320
  padding: 10px 12px;
280
- border: 1px solid light-dark(#d9dee8, #394352);
281
- border-radius: 10px;
282
- background: light-dark(#fbfcfe, #11171f);
321
+ border: 1px solid var(--dc-border);
322
+ border-radius: 8px;
323
+ background: var(--dc-page);
283
324
  color: inherit;
284
325
  font: inherit;
285
326
  font-size: 12px;
@@ -291,8 +332,8 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
291
332
  gap: 10px;
292
333
  padding: 12px;
293
334
  border: 1px dashed light-dark(#b9c5d8, #43516a);
294
- border-radius: 10px;
295
- color: light-dark(#59677c, #b1bdd0);
335
+ border-radius: 8px;
336
+ color: var(--dc-muted);
296
337
  font-size: 12px;
297
338
  }
298
339
  .dcAgentPromptFile input { max-width: 100%; }
@@ -302,17 +343,17 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
302
343
  padding: 12px;
303
344
  border: 1px dashed light-dark(#b9c5d8, #43516a);
304
345
  border-radius: 12px;
305
- background: light-dark(#fbfcfe, #11171f);
346
+ background: var(--dc-page);
306
347
  outline: none;
307
348
  }
308
349
  .dcAgentPromptImageDrop.is-active {
309
- border-color: #2869e6;
310
- background: light-dark(#edf4ff, #172841);
350
+ border-color: var(--dc-action);
351
+ background: var(--dc-selected);
311
352
  }
312
353
  .dcAgentPromptImageDrop > p {
313
354
  margin: 0;
314
- color: light-dark(#697386, #aab5c7);
315
- font-size: 11px;
355
+ color: var(--dc-muted);
356
+ font-size: 12px;
316
357
  line-height: 17px;
317
358
  }
318
359
  .dcAgentPromptImagePreview {
@@ -327,25 +368,25 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
327
368
  flex: 0 0 auto;
328
369
  overflow: hidden;
329
370
  padding: 0;
330
- border: 1px solid light-dark(#d9dee8, #394352);
331
- border-radius: 10px;
332
- background: light-dark(#f3f6fa, #202733);
371
+ border: 1px solid var(--dc-border);
372
+ border-radius: 8px;
373
+ background: var(--dc-page);
333
374
  cursor: zoom-in;
334
375
  }
335
376
  .dcAgentPromptImageThumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
336
377
  .dcAgentPromptImageMeta { min-width: 0; flex: 1 1 auto; }
337
378
  .dcAgentPromptImageMeta b,
338
379
  .dcAgentPromptImageMeta small { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
339
- .dcAgentPromptImageMeta small { margin-top: 3px; color: light-dark(#697386, #aab5c7); }
380
+ .dcAgentPromptImageMeta small { margin-top: 3px; color: var(--dc-muted); }
340
381
  .dcAgentPromptImageRemove {
341
382
  flex: 0 0 auto;
342
383
  padding: 5px 9px;
343
- border: 1px solid light-dark(#d9dee8, #394352);
384
+ border: 1px solid var(--dc-border);
344
385
  border-radius: 8px;
345
386
  background: transparent;
346
387
  color: inherit;
347
388
  font: inherit;
348
- font-size: 11px;
389
+ font-size: 12px;
349
390
  cursor: pointer;
350
391
  }
351
392
  .dcAgentImageLightbox {
@@ -376,25 +417,25 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
376
417
  margin: 10px 0 0;
377
418
  padding: 8px 10px;
378
419
  border-radius: 8px;
379
- background: light-dark(#f6f8fb, #1c2330);
380
- color: light-dark(#697386, #aab5c7);
381
- font-size: 11px;
420
+ background: var(--dc-page);
421
+ color: var(--dc-muted);
422
+ font-size: 12px;
382
423
  line-height: 17px;
383
424
  }
384
- .dcAgentPromptError { margin: 8px 0 0; color: light-dark(#b42318, #ff8d86); font-size: 11px; }
425
+ .dcAgentPromptError { margin: 8px 0 0; color: light-dark(#b42318, #ff8d86); font-size: 12px; }
385
426
  .dcAgentPromptActions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 14px; }
386
427
  .dcAgentPromptAction {
387
428
  min-height: 34px;
388
429
  padding: 6px 13px;
389
- border: 1px solid light-dark(#d9dee8, #394352);
390
- border-radius: 9px;
430
+ border: 1px solid var(--dc-border);
431
+ border-radius: 6px;
391
432
  background: transparent;
392
433
  color: inherit;
393
434
  font: inherit;
394
435
  font-size: 12px;
395
436
  cursor: pointer;
396
437
  }
397
- .dcAgentPromptAction.is-primary { border-color: #2869e6; background: #2869e6; color: white; }
438
+ .dcAgentPromptAction.is-primary { border-color: var(--dc-action); background: var(--dc-action); color: var(--dc-on-action); }
398
439
  .dcAgentPromptAction:disabled { opacity: .5; cursor: default; }
399
440
 
400
441
  .dcAgentHeaderAction {
@@ -403,9 +444,9 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
403
444
  gap: 6px;
404
445
  min-height: 30px;
405
446
  padding: 4px 9px;
406
- border: 1px solid light-dark(#d9dee8, #394352);
447
+ border: 1px solid var(--dc-border);
407
448
  border-radius: 8px;
408
- background: light-dark(#ffffff, #191f28);
449
+ background: var(--dc-surface);
409
450
  color: inherit;
410
451
  font: inherit;
411
452
  font-size: 12px;
@@ -413,8 +454,8 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
413
454
  }
414
455
  .dcAgentHeaderAction:hover,
415
456
  .dcAgentHeaderAction:focus-visible {
416
- border-color: light-dark(#2869e6, #6d9eff);
417
- color: light-dark(#1556cf, #8cb3ff);
457
+ border-color: var(--dc-action);
458
+ color: var(--dc-action);
418
459
  }
419
460
 
420
461
  .dcAgentWbHeader {
@@ -422,7 +463,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
422
463
  align-items: center;
423
464
  gap: 8px;
424
465
  padding: 12px 14px;
425
- border-bottom: 1px solid light-dark(#e4e8f0, #303947);
466
+ border-bottom: 1px solid var(--dc-border);
426
467
  }
427
468
 
428
469
  .dcAgentWbTitle {
@@ -439,15 +480,15 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
439
480
  display: grid;
440
481
  place-items: center;
441
482
  flex: 0 0 auto;
442
- border-radius: 11px;
483
+ border-radius: 8px;
443
484
  font-size: 18px;
444
- background: light-dark(#edf4ff, #172841);
485
+ background: var(--dc-selected);
445
486
  }
446
487
 
447
488
  .dcAgentWbTitle b,
448
489
  .dcAgentWbTitle small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
449
490
  .dcAgentWbTitle b { display: block; font-size: 15px; }
450
- .dcAgentWbTitle small { display: block; max-width: 190px; color: light-dark(#697386, #aab5c7); font-size: 11px; }
491
+ .dcAgentWbTitle small { display: block; max-width: 190px; color: var(--dc-muted); font-size: 12px; }
451
492
 
452
493
  .dcAgentWbActions {
453
494
  display: flex;
@@ -460,10 +501,10 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
460
501
  .dcAgentQccBadge {
461
502
  flex: 0 0 auto;
462
503
  padding: 4px 10px;
463
- border: 1px solid light-dark(#e4e8f0, #303947);
504
+ border: 1px solid var(--dc-border);
464
505
  border-radius: 999px;
465
- color: light-dark(#697386, #aab5c7);
466
- font-size: 11px;
506
+ color: var(--dc-muted);
507
+ font-size: 12px;
467
508
  white-space: nowrap;
468
509
  }
469
510
 
@@ -473,22 +514,22 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
473
514
  height: 30px;
474
515
  display: grid;
475
516
  place-items: center;
476
- border: 1px solid light-dark(#e4e8f0, #303947);
517
+ border: 1px solid var(--dc-border);
477
518
  border-radius: 8px;
478
519
  background: transparent;
479
520
  color: inherit;
480
521
  font-size: 15px;
481
522
  cursor: pointer;
482
523
  }
483
- .dcAgentWbClose:hover, .dcAgentWbClose:focus-visible { background: light-dark(#f6f8fb, #202733); }
524
+ .dcAgentWbClose:hover, .dcAgentWbClose:focus-visible { background: var(--dc-page); }
484
525
 
485
526
  .dcAgentStepper {
486
527
  display: grid;
487
528
  grid-template-columns: repeat(4, minmax(0, 1fr));
488
529
  gap: 8px;
489
530
  padding: 12px 18px;
490
- border-bottom: 1px solid light-dark(#e4e8f0, #303947);
491
- background: light-dark(#fbfcfe, #12171e);
531
+ border-bottom: 1px solid var(--dc-border);
532
+ background: var(--dc-page);
492
533
  }
493
534
 
494
535
  .dcAgentStep {
@@ -497,18 +538,18 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
497
538
  justify-content: center;
498
539
  gap: 6px;
499
540
  padding: 9px 6px;
500
- border: 1px solid light-dark(#e4e8f0, #303947);
501
- border-radius: 9px;
541
+ border: 1px solid var(--dc-border);
542
+ border-radius: 6px;
502
543
  background: transparent;
503
- color: light-dark(#697386, #aab5c7);
544
+ color: var(--dc-muted);
504
545
  font-size: 12px;
505
546
  cursor: pointer;
506
547
  white-space: nowrap;
507
548
  }
508
549
  .dcAgentStep.is-active {
509
- color: light-dark(#1556cf, #8cb3ff);
510
- border-color: light-dark(#2869e6, #6d9eff);
511
- background: light-dark(#edf4ff, #172841);
550
+ color: var(--dc-action);
551
+ border-color: var(--dc-action);
552
+ background: var(--dc-selected);
512
553
  }
513
554
 
514
555
  .dcAgentWbBody {
@@ -518,16 +559,16 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
518
559
  }
519
560
 
520
561
  .dcAgentPane { display: flex; flex-direction: column; gap: 14px; }
521
- .dcAgentHint { margin: 0; color: light-dark(#697386, #aab5c7); font-size: 13px; line-height: 1.6; }
562
+ .dcAgentHint { margin: 0; color: var(--dc-muted); font-size: 13px; line-height: 1.6; }
522
563
 
523
564
  .dcAgentTextarea {
524
565
  width: 100%;
525
566
  box-sizing: border-box;
526
567
  min-height: 132px;
527
568
  padding: 12px;
528
- border: 1px solid light-dark(#cfd6e2, #485364);
529
- border-radius: 10px;
530
- background: light-dark(#ffffff, #191f28);
569
+ border: 1px solid var(--dc-border);
570
+ border-radius: 8px;
571
+ background: var(--dc-surface);
531
572
  color: inherit;
532
573
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
533
574
  font-size: 12px;
@@ -540,29 +581,29 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
540
581
  box-sizing: border-box;
541
582
  min-width: 0;
542
583
  padding: 8px 12px;
543
- border: 1px solid light-dark(#cfd6e2, #485364);
544
- border-radius: 9px;
584
+ border: 1px solid var(--dc-border);
585
+ border-radius: 6px;
545
586
  font-size: 12px;
546
- background: light-dark(#ffffff, #191f28);
587
+ background: var(--dc-surface);
547
588
  color: inherit;
548
589
  }
549
590
 
550
591
  .dcAgentButton {
551
592
  padding: 9px 16px;
552
- border: 1px solid light-dark(#cfd6e2, #485364);
553
- border-radius: 9px;
554
- background: light-dark(#ffffff, #191f28);
593
+ border: 1px solid var(--dc-border);
594
+ border-radius: 6px;
595
+ background: var(--dc-surface);
555
596
  color: inherit;
556
597
  font-size: 13px;
557
598
  cursor: pointer;
558
599
  }
559
- .dcAgentButton:hover, .dcAgentButton:focus-visible { border-color: light-dark(#2869e6, #6d9eff); }
600
+ .dcAgentButton:hover, .dcAgentButton:focus-visible { border-color: var(--dc-action); }
560
601
  .dcAgentButton.is-primary {
561
602
  border-color: transparent;
562
- color: #ffffff;
563
- background: light-dark(#2869e6, #3d7bf0);
603
+ color: var(--dc-on-action);
604
+ background: var(--dc-action);
564
605
  }
565
- .dcAgentButton.is-primary:hover, .dcAgentButton.is-primary:focus-visible { background: light-dark(#1556cf, #6d9eff); }
606
+ .dcAgentButton.is-primary:hover, .dcAgentButton.is-primary:focus-visible { background: var(--dc-hover); }
566
607
  .dcAgentButton:disabled { opacity: 0.5; cursor: not-allowed; }
567
608
 
568
609
  .dcAgentGrid {
@@ -573,14 +614,14 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
573
614
 
574
615
  .dcAgentCard {
575
616
  padding: 12px 14px;
576
- border: 1px solid light-dark(#e4e8f0, #303947);
577
- border-radius: 11px;
578
- background: light-dark(#fbfcfe, #191f28);
617
+ border: 1px solid var(--dc-border);
618
+ border-radius: 8px;
619
+ background: var(--dc-page);
579
620
  }
580
- .dcAgentCard span { display: block; color: light-dark(#697386, #aab5c7); font-size: 11px; }
621
+ .dcAgentCard span { display: block; color: var(--dc-muted); font-size: 12px; }
581
622
  .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); }
623
+ .dcAgentCard b.is-good { color: var(--dc-success); }
624
+ .dcAgentCard b.is-warn { color: var(--dc-review); }
584
625
  .dcAgentCard b.is-bad { color: light-dark(#d2454f, #ff838b); }
585
626
 
586
627
  .dcAgentTable {
@@ -591,9 +632,9 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
591
632
  .dcAgentTable th, .dcAgentTable td {
592
633
  padding: 7px 9px;
593
634
  text-align: left;
594
- border-bottom: 1px solid light-dark(#eef1f6, #242b36);
635
+ border-bottom: 1px solid var(--dc-border);
595
636
  }
596
- .dcAgentTable th { color: light-dark(#697386, #aab5c7); font-weight: 600; }
637
+ .dcAgentTable th { color: var(--dc-muted); font-weight: 600; }
597
638
  .dcAgentTable td.num { font-variant-numeric: tabular-nums; }
598
639
  .dcAgentTableWrap { max-width: 100%; overflow-x: auto; }
599
640
  .dcAgentTableWrap .dcAgentTable { min-width: 720px; table-layout: auto; }
@@ -605,7 +646,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
605
646
  .dcAgentError {
606
647
  padding: 10px 12px;
607
648
  border: 1px solid light-dark(#ffd6d8, #5b2f33);
608
- border-radius: 9px;
649
+ border-radius: 6px;
609
650
  background: light-dark(#fff0f0, #351d21);
610
651
  color: light-dark(#d2454f, #ff838b);
611
652
  font-size: 12px;
@@ -614,22 +655,22 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
614
655
  .dcAgentChips { display: flex; flex-wrap: wrap; gap: 6px; }
615
656
  .dcAgentChip {
616
657
  padding: 4px 10px;
617
- border: 1px solid light-dark(#e4e8f0, #303947);
658
+ border: 1px solid var(--dc-border);
618
659
  border-radius: 999px;
619
- font-size: 11px;
620
- color: light-dark(#697386, #aab5c7);
660
+ font-size: 12px;
661
+ color: var(--dc-muted);
621
662
  }
622
663
  .dcAgentChip.is-selected {
623
- color: light-dark(#1556cf, #8cb3ff);
624
- border-color: light-dark(#2869e6, #6d9eff);
625
- background: light-dark(#edf4ff, #172841);
664
+ color: var(--dc-action);
665
+ border-color: var(--dc-action);
666
+ background: var(--dc-selected);
626
667
  }
627
668
  .dcAgentCheck { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; }
628
669
  .dcAgentSection {
629
670
  padding: 14px;
630
- border: 1px solid light-dark(#e4e8f0, #303947);
631
- border-radius: 11px;
632
- background: light-dark(#fbfcfe, #191f28);
671
+ border: 1px solid var(--dc-border);
672
+ border-radius: 8px;
673
+ background: var(--dc-page);
633
674
  }
634
675
  .dcAgentSection h3 { margin: 0 0 8px; font-size: 13px; }
635
676
  .dcAgentCandidate {
@@ -638,32 +679,32 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
638
679
  gap: 10px;
639
680
  align-items: center;
640
681
  padding: 10px 0;
641
- border-bottom: 1px solid light-dark(#eef1f6, #242b36);
682
+ border-bottom: 1px solid var(--dc-border);
642
683
  }
643
684
  .dcAgentCandidate:last-child { border-bottom: 0; }
644
- .dcAgentCandidate small { color: light-dark(#697386, #aab5c7); }
685
+ .dcAgentCandidate small { color: var(--dc-muted); }
645
686
  .dcAgentProgress { height: 8px; overflow: hidden; border-radius: 99px; background: light-dark(#e8edf5, #293240); }
646
- .dcAgentProgress > span { display: block; height: 100%; background: #2869e6; }
687
+ .dcAgentProgress > span { display: block; height: 100%; background: var(--dc-action); }
647
688
 
648
689
  /* M3 · overlay 头部 jobs 状态 pill(轮询 /mvp/jobs,不接计费遥测)。 */
649
690
  .dcAgentJobsPill {
650
691
  flex: 0 0 auto;
651
692
  padding: 4px 10px;
652
- border: 1px solid light-dark(#e4e8f0, #303947);
693
+ border: 1px solid var(--dc-border);
653
694
  border-radius: 999px;
654
- font-size: 11px;
695
+ font-size: 12px;
655
696
  white-space: nowrap;
656
- color: light-dark(#697386, #aab5c7);
697
+ color: var(--dc-muted);
657
698
  }
658
699
  .dcAgentJobsPill[data-state='running'] {
659
- color: light-dark(#1556cf, #8cb3ff);
660
- border-color: light-dark(#2869e6, #6d9eff);
661
- background: light-dark(#edf4ff, #172841);
700
+ color: var(--dc-action);
701
+ border-color: var(--dc-action);
702
+ background: var(--dc-selected);
662
703
  }
663
704
  .dcAgentJobsPill[data-state='completed'] {
664
- color: light-dark(#118a5b, #56d39b);
665
- border-color: light-dark(#118a5b, #2f7d5e);
666
- background: light-dark(#eefaf3, #12261d);
705
+ color: var(--dc-success);
706
+ border-color: var(--dc-success);
707
+ background: var(--dc-success-bg);
667
708
  }
668
709
  .dcAgentJobsPill[data-state='failed'] {
669
710
  color: light-dark(#d2454f, #ff838b);
@@ -677,9 +718,9 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
677
718
  flex-direction: column;
678
719
  gap: 8px;
679
720
  padding: 12px 14px;
680
- border: 1px solid light-dark(#e4e8f0, #303947);
681
- border-radius: 11px;
682
- background: light-dark(#fbfcfe, #191f28);
721
+ border: 1px solid var(--dc-border);
722
+ border-radius: 8px;
723
+ background: var(--dc-page);
683
724
  margin: 4px 0;
684
725
  }
685
726
  .dcAgentToolCardHead {
@@ -699,34 +740,34 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
699
740
  flex: 0 0 auto;
700
741
  padding: 1px 8px;
701
742
  border-radius: 999px;
702
- font-size: 11px;
703
- color: light-dark(#697386, #aab5c7);
704
- border: 1px solid light-dark(#e4e8f0, #303947);
743
+ font-size: 12px;
744
+ color: var(--dc-muted);
745
+ border: 1px solid var(--dc-border);
705
746
  }
706
- .dcAgentToolCardState.is-ok { color: light-dark(#118a5b, #56d39b); }
747
+ .dcAgentToolCardState.is-ok { color: var(--dc-success); }
707
748
  .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); }
749
+ .dcAgentToolCardState.is-running { color: var(--dc-action); }
750
+ .dcAgentToolCardState.is-stopped { color: var(--dc-muted); }
710
751
  .dcAgentToolCardBody {
711
752
  margin: 0;
712
753
  white-space: pre-wrap;
713
754
  word-break: break-word;
714
755
  font-size: 12px;
715
756
  line-height: 1.6;
716
- color: light-dark(#33415a, #c9d4e5);
757
+ color: var(--dc-text);
717
758
  }
718
- .dcAgentHistoryTask { border: 1px solid light-dark(#dce4f1, #344052); border-radius: 9px; background: light-dark(#fff, #1b222e); color: inherit; font: inherit; cursor: pointer; }
759
+ .dcAgentHistoryTask { border: 1px solid var(--dc-border); border-radius: 6px; background: var(--dc-surface); color: inherit; font: inherit; cursor: pointer; }
719
760
  .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; }
761
+ .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; }
762
+ .dcAgentWizardStep b { display: grid; place-items: center; width: 20px; height: 20px; border-radius: 50%; background: var(--dc-border); color: var(--dc-muted); }
763
+ .dcAgentWizardStep.is-active { border-color: var(--dc-action); background: var(--dc-selected); color: var(--dc-action); }
764
+ .dcAgentWizardStep.is-active b { background: var(--dc-action); color: var(--dc-on-action); }
724
765
  .dcAgentWizardPane { min-height: 230px; }
725
766
  .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; }
767
+ .dcAgentWizardPane > p { margin: 0 0 12px; color: var(--dc-muted); font-size: 12px; line-height: 17px; }
727
768
  .dcAgentPromptRules { display: grid; gap: 8px; margin-top: 14px; }
728
769
  .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; }
770
+ .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
771
  .dcAgentFormField { display: grid; gap: 6px; font-size: 12px; font-weight: 600; }
731
772
  .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
773
  .dcAgentMappingRow > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@@ -742,13 +783,13 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
742
783
  border: 0;
743
784
  border-radius: 6px;
744
785
  background: transparent;
745
- color: light-dark(#2869e6, #8cb3ff);
786
+ color: var(--dc-action);
746
787
  font: inherit;
747
- font-size: 11px;
788
+ font-size: 12px;
748
789
  cursor: pointer;
749
790
  }
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; }
791
+ .dcAgentFieldAction:hover, .dcAgentFieldAction:focus-visible { background: var(--dc-selected); }
792
+ .dcAgentPreviewTable { margin-top: 12px; overflow: auto; border: 1px solid var(--dc-border); border-radius: 8px; }
752
793
  .dcAgentHistoryTask { display: block; width: 100%; padding: 10px; text-align: left; }
753
794
  .dcAgentHistoryTask h3 { margin: 0; font-size: 12px; }
754
795
  /*
@@ -793,6 +834,38 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
793
834
  .dcAgentWorkbench { width: 420px; max-width: 48vw; min-width: 360px; }
794
835
  .dcAgentQccBadge, .dcAgentJobsPill { display: none; }
795
836
  }
837
+ /* Distinct levels: management tabs → compact task steps → working content. */
838
+ .dcAgentWorkbench, .dcAgentPromptPanel { font-size: 14px; line-height: 1.5; }
839
+ .dcAgentWbHeader, .dcAgentManagement, .dcAgentStepper { flex: none; }
840
+ .dcAgentManagement { display: flex; gap: 24px; padding: 0 18px; border-bottom: 1px solid var(--dc-border); }
841
+ .dcAgentManagement .dcAgentButton { border: 0; border-bottom: 3px solid transparent; border-radius: 0; padding: 10px 0; background: transparent; }
842
+ .dcAgentManagement .dcAgentButton[aria-pressed="true"] { border-bottom-color: var(--dc-action); color: var(--dc-action); font-weight: 600; }
843
+ .dcAgentStepper { display: flex; overflow-x: auto; gap: 4px; padding: 10px 12px; }
844
+ .dcAgentStep { flex: 0 0 auto; border-color: transparent; padding: 7px 8px; }
845
+ .dcAgentStep.is-active { border-color: transparent; }
846
+ .dcAgentCapability { border-radius: 8px; }
847
+ .dcAgentWbBody { min-height: 0; }
848
+ .dcAgentTable th { background: var(--dc-table-head); color: var(--dc-text); }
849
+ .dcAgentTable th, .dcAgentTable td { height: 44px; box-sizing: border-box; font-size: 13px; }
850
+ .dcAgentTable tbody tr:hover { background: var(--dc-selected); }
851
+ .dcAgentSection, .dcAgentCard { background: var(--dc-surface); }
852
+ .dcAgentFieldGroup { background: var(--dc-page); padding: 12px; border-radius: 8px; }
853
+ .dcAgentPromptFieldGrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 8px; margin-top: 10px; }
854
+ .dcAgentPromptFieldGrid .dcAgentPromptChoice { border: 0; border-radius: 4px; min-width: 0; align-items: flex-start; font-size: 13px; }
855
+ .dcAgentFieldGroup .dcAgentChips { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
856
+ .dcAgentFieldGroup .dcAgentChip { border-radius: 4px; }
857
+ .dcAgentPromptText, .dcAgentTextarea, .dcAgentField { font-size: 14px; }
858
+ .dcAgentPromptTrigger { border-radius: 6px; }
859
+ .dcAgentPromptAction.is-primary:hover:not(:disabled) { background: var(--dc-hover); }
860
+ :is(.dcAgentWorkbench, .dcAgentPromptPanel, .dcAgentCapabilities, .dcAgentPromptLayer) :is(button, input, select, textarea, summary):focus-visible,
861
+ .dcAgentLauncher:focus-visible { outline: 2px solid var(--dc-action); outline-offset: 2px; }
862
+ @media (max-width: 760px) {
863
+ [data-dc-agent-hero-title="true"] { font-size: 20px; }
864
+ .dcAgentHeroLogo { width: 40px; height: 40px; border-radius: 8px; }
865
+ .dcAgentPromptText, .dcAgentTextarea, .dcAgentField { font-size: 16px; }
866
+ .dcAgentPromptFieldGrid { grid-template-columns: 1fr; }
867
+ }
868
+
796
869
  `;
797
870
 
798
871
  /** 安装入口、会话能力按钮与右侧工作台样式。 */
@@ -851,7 +924,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
851
924
  { key: 'upload', label: '导入名单', icon: IconPaperclipOutline16, fallback: '+' },
852
925
  { key: 'profile', label: '质量体检', icon: IconChecklistOutline14, fallback: '✓' },
853
926
  { key: 'match', label: '匹配核验', icon: IconSearchOutline16, fallback: '⌕' },
854
- { key: 'enrich', label: '字段补全', icon: IconDataOutline16, fallback: '▦' },
927
+ { key: 'enrich', label: '字段补全', icon: DatabaseLogo, fallback: '▦' },
855
928
  { key: 'history', label: '任务历史', icon: IconArchiveOutline20, fallback: '◷' },
856
929
  ];
857
930
 
@@ -1735,7 +1808,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
1735
1808
  console.error('[dc-agent] open failed:', error);
1736
1809
  }
1737
1810
  },
1738
- children: wide ? '🧹 数据清洗补全' : '🧹',
1811
+ children: h('span', { className: 'dcAgentLauncherContent' }, h(DatabaseLogo), wide ? h('span', null, '数据清洗补全') : null),
1739
1812
  });
1740
1813
  if (!topMount || typeof reactDom.createPortal !== 'function') return launcher;
1741
1814
  return reactDom.createPortal(h('div', {
@@ -1889,6 +1962,9 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
1889
1962
  if (!hero) return () => {};
1890
1963
  const changedTitles = new Map();
1891
1964
  const changedBadges = new Map();
1965
+ const changedMarks = new Map();
1966
+ const changedRows = new Map();
1967
+ const ownedLogos = new Map();
1892
1968
  const hiddenForeignDocks = new Map();
1893
1969
  const composerStack = marker?.parentElement?.parentElement;
1894
1970
  // 单一会话所有权由入口的 enabled 参数(useCleaningSession(sessionId) && composerPhase==='blank')
@@ -1910,6 +1986,29 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
1910
1986
  if (!changedTitles.has(title)) changedTitles.set(title, title.textContent ?? '');
1911
1987
  title.dataset.dcAgentHeroTitle = 'true';
1912
1988
  if (title.textContent !== '数据清洗补全智能体') { title.textContent = '数据清洗补全智能体'; mutated = true; }
1989
+ // 只适配本会话已确认的 DSH headline;未知宿主结构保留原状。
1990
+ const row = title.parentElement;
1991
+ const nativeMark = row?.querySelector?.('[class*="fishHitbox"]');
1992
+ if (nativeMark && typeof document.createElementNS === 'function') {
1993
+ if (!changedRows.has(row)) changedRows.set(row, row.getAttribute('data-dc-agent-hero-row'));
1994
+ row.setAttribute('data-dc-agent-hero-row', 'true');
1995
+ if (!changedMarks.has(nativeMark)) changedMarks.set(nativeMark, nativeMark.style.display);
1996
+ nativeMark.style.display = 'none';
1997
+ if (!ownedLogos.get(row)?.isConnected) {
1998
+ const logo = document.createElement('span');
1999
+ logo.className = 'dcAgentHeroLogo';
2000
+ logo.setAttribute('aria-hidden', 'true');
2001
+ const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
2002
+ 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);
2003
+ const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
2004
+ path.setAttribute('d', DATABASE_PATH);
2005
+ svg.appendChild(path);
2006
+ logo.appendChild(svg);
2007
+ row.insertBefore(logo, title);
2008
+ ownedLogos.set(row, logo);
2009
+ mutated = true;
2010
+ }
2011
+ }
1913
2012
  }
1914
2013
  if (badge) {
1915
2014
  if (!changedBadges.has(badge)) changedBadges.set(badge, badge.style?.display ?? '');
@@ -1947,6 +2046,12 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
1947
2046
  observer?.observe?.(hero, { childList: true, subtree: true });
1948
2047
  return () => {
1949
2048
  observer?.disconnect?.();
2049
+ for (const logo of ownedLogos.values()) logo.remove();
2050
+ for (const [mark, originalDisplay] of changedMarks) mark.style.display = originalDisplay;
2051
+ for (const [row, originalValue] of changedRows) {
2052
+ if (originalValue === null) row.removeAttribute('data-dc-agent-hero-row');
2053
+ else row.setAttribute('data-dc-agent-hero-row', originalValue);
2054
+ }
1950
2055
  for (const [title, originalText] of changedTitles) {
1951
2056
  if (title.textContent === '数据清洗补全智能体') title.textContent = originalText;
1952
2057
  delete title.dataset.dcAgentHeroTitle;
@@ -2064,6 +2169,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
2064
2169
  const [imageLightbox, setImageLightbox] = react.useState(false);
2065
2170
  const [cleaningKeys, setCleaningKeys] = react.useState(DEFAULT_CLEANING_KEYS);
2066
2171
  const [enrichmentKeys, setEnrichmentKeys] = react.useState(DEFAULT_ENRICHMENT_KEYS);
2172
+ const [fieldQuery, setFieldQuery] = react.useState('');
2067
2173
  const [anchorKeys, setAnchorKeys] = react.useState(['company_name', 'credit_no']);
2068
2174
  const [matchRules, setPromptMatchRules] = react.useState({
2069
2175
  normalizeNames: true,
@@ -2501,18 +2607,27 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
2501
2607
  h('b', null, '清洗目标'),
2502
2608
  h('div', { className: 'dcAgentPromptChoices' }, choice(CLEANING_OPTIONS, cleaningKeys, setCleaningKeys)),
2503
2609
  ),
2504
- FIELD_GROUPS.map(([groupId, label, fields, sourceTool]) => h('div', { className: 'dcAgentPromptGroup', key: groupId },
2610
+ h('label', { className: 'dcAgentPromptField' },
2611
+ h('span', null, `查找补全字段 · 已选 ${enrichmentKeys.length}`),
2612
+ h('input', { type: 'search', className: 'dcAgentField', value: fieldQuery, 'aria-label': '查找补全字段',
2613
+ placeholder: '搜索维度、字段或工具名称', onChange: (event) => setFieldQuery(event.target.value) })),
2614
+ !FIELD_GROUPS.some((group) => visibleCatalogFields(group, fieldQuery).length) ? h('p', { className: 'dcAgentHint', role: 'status' }, '没有匹配的字段;已选字段保持不变。') : null,
2615
+ FIELD_GROUPS.filter((group) => visibleCatalogFields(group, fieldQuery).length).map(([groupId, label, fields, sourceTool]) => h('div', { className: 'dcAgentPromptGroup dcAgentFieldGroup', key: groupId },
2505
2616
  h('div', { className: 'dcAgentFieldGroupHead' },
2506
2617
  h('div', null,
2507
2618
  h('b', null, `${label} · ${fields.filter(([id]) => enrichmentKeys.includes(id)).length}/${fields.length}`),
2508
2619
  sourceTool ? h('small', { className: 'dcAgentHint' }, `来源:${sourceTool}`) : null,
2509
2620
  ),
2510
2621
  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) }, '清空'),
2622
+ h('button', { type: 'button', className: 'dcAgentFieldAction', title: '选中本维度全部字段,不受搜索过滤影响', onClick: () => setPromptFieldGroup(fields, true) }, '全选'),
2623
+ h('button', { type: 'button', className: 'dcAgentFieldAction', title: '清空本维度全部字段,不受搜索过滤影响', onClick: () => setPromptFieldGroup(fields, false) }, '清空'),
2513
2624
  ),
2514
2625
  ),
2515
- h('div', { className: 'dcAgentPromptChoices' }, choice(fields, enrichmentKeys, setEnrichmentKeys)),
2626
+ h('div', { className: 'dcAgentPromptFieldGrid' }, visibleCatalogFields([groupId, label, fields, sourceTool], fieldQuery).map(([id, fieldLabel]) => h('label', {
2627
+ key: id, className: `dcAgentPromptChoice${enrichmentKeys.includes(id) ? ' is-selected' : ''}`,
2628
+ }, h('input', { type: 'checkbox', checked: enrichmentKeys.includes(id),
2629
+ onChange: (event) => setEnrichmentKeys((current) => event.target.checked ? [...new Set([...current, id])] : current.filter((key) => key !== id)),
2630
+ }), fieldLabel))),
2516
2631
  )),
2517
2632
  ) : null,
2518
2633
  wizardStep === 4 ? h('div', { className: 'dcAgentWizardPane' },
@@ -2553,9 +2668,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
2553
2668
  title: '打开数据清洗补全工作台',
2554
2669
  onClick: () => requestWorkbenchOpen(null, sessionId),
2555
2670
  },
2556
- typeof IconDataOutline16 === 'function'
2557
- ? h(IconDataOutline16, { size: 16, 'aria-hidden': 'true' })
2558
- : h('span', { 'aria-hidden': 'true' }, '▦'),
2671
+ h(DatabaseLogo, { size: 16 }),
2559
2672
  h('span', null, '清洗补全工作台'),
2560
2673
  );
2561
2674
  }
@@ -2830,6 +2943,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
2830
2943
  const paidConfirmed = useStore((state) => state.paidConfirmed);
2831
2944
  const jobs = useStore((state) => state.jobs);
2832
2945
  const activeSessionId = useStore((state) => state.activeSessionId);
2946
+ const [fieldQuery, setFieldQuery] = react.useState('');
2833
2947
 
2834
2948
  react.useEffect(() => {
2835
2949
  rootWorkbenchActions = actions;
@@ -3576,18 +3690,22 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
3576
3690
  h('span', { className: 'dcAgentChip' }, '第一批 40'),
3577
3691
  h('span', { className: 'dcAgentChip' }, '第二批 58'),
3578
3692
  ),
3579
- uiFieldGroups.map(([groupId, label, fields, sourceTool]) => h('div', { key: groupId, className: 'dcAgentFieldGroup' },
3693
+ h('label', { className: 'dcAgentPromptField' }, h('span', null, '查找补全字段'),
3694
+ h('input', { type: 'search', className: 'dcAgentField', value: fieldQuery, 'aria-label': '查找补全字段',
3695
+ placeholder: '搜索维度、字段或工具名称', onChange: (event) => setFieldQuery(event.target.value) })),
3696
+ !uiFieldGroups.some((group) => visibleCatalogFields(group, fieldQuery).length) ? h('p', { className: 'dcAgentHint', role: 'status' }, '没有匹配的字段;已选字段保持不变。') : null,
3697
+ uiFieldGroups.filter((group) => visibleCatalogFields(group, fieldQuery).length).map(([groupId, label, fields, sourceTool]) => h('div', { key: groupId, className: 'dcAgentFieldGroup' },
3580
3698
  h('div', { className: 'dcAgentFieldGroupHead' },
3581
3699
  h('div', null,
3582
3700
  h('b', null, `${label} · ${fields.filter(([id]) => fieldSelection.includes(id)).length}/${fields.length}`),
3583
3701
  sourceTool ? h('small', { className: 'dcAgentHint' }, `来源:${sourceTool}`) : null,
3584
3702
  ),
3585
3703
  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) }, '清空'),
3704
+ h('button', { type: 'button', className: 'dcAgentFieldAction', title: '选中本维度全部字段,不受搜索过滤影响', onClick: () => setWorkbenchFieldGroup(fields, true) }, '全选'),
3705
+ h('button', { type: 'button', className: 'dcAgentFieldAction', title: '清空本维度全部字段,不受搜索过滤影响', onClick: () => setWorkbenchFieldGroup(fields, false) }, '清空'),
3588
3706
  ),
3589
3707
  ),
3590
- h('div', { className: 'dcAgentChips' }, fields.map(([key, fieldLabel]) => h('label', { key, className: `dcAgentChip${fieldSelection.includes(key) ? ' is-selected' : ''}` },
3708
+ h('div', { className: 'dcAgentChips' }, visibleCatalogFields([groupId, label, fields, sourceTool], fieldQuery).map(([key, fieldLabel]) => h('label', { key, className: `dcAgentChip${fieldSelection.includes(key) ? ' is-selected' : ''}` },
3591
3709
  h('input', { type: 'checkbox', checked: fieldSelection.includes(key), onChange: () => actions.toggleField(key) }), ` ${fieldLabel}`,
3592
3710
  ))),
3593
3711
  )),
@@ -3823,7 +3941,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
3823
3941
  },
3824
3942
  h('header', { className: 'dcAgentWbHeader' },
3825
3943
  h('div', { className: 'dcAgentWbTitle' },
3826
- h('span', { className: 'dcAgentWbIcon', 'aria-hidden': 'true' }, '🧹'),
3944
+ h('span', { className: 'dcAgentWbIcon', 'aria-hidden': 'true' }, h(DatabaseLogo, { size: 22 })),
3827
3945
  h('div', null,
3828
3946
  h('b', null, '数据清洗补全'),
3829
3947
  h('small', null, cachedTask ? `${WORKFLOW_STATE_LABELS[cachedTask.state] || cachedTask.state} · ${cachedTask.id.slice(0, 18)}` : '正在创建 Host taskId…'),
@@ -3853,7 +3971,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
3853
3971
  }, '✕'),
3854
3972
  ),
3855
3973
  ),
3856
- h('nav', { className: 'dcAgentRow', style: { padding: '10px 16px' }, 'aria-label': '工作台管理' },
3974
+ h('nav', { className: 'dcAgentManagement', 'aria-label': '工作台管理' },
3857
3975
  h('button', { type: 'button', className: 'dcAgentButton', 'aria-pressed': step !== 'history',
3858
3976
  onClick: () => actions.setStep(cachedTask?.stage || 'upload') }, '当前任务'),
3859
3977
  h('button', { type: 'button', className: 'dcAgentButton', 'aria-pressed': step === 'history',
@@ -3984,6 +4102,8 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
3984
4102
  exports.inject = inject;
3985
4103
  // 测试用纯函数,不构成 Host / DSH 稳定 API。
3986
4104
  exports.__testing = {
4105
+ DatabaseLogo,
4106
+ visibleCatalogFields,
3987
4107
  installCapabilityMount,
3988
4108
  PromptDialog,
3989
4109
  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.8",
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",