dsh-data-cleaning-agent 0.9.10 → 0.9.12
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 +12 -0
- package/README.en.md +3 -1
- package/README.md +4 -2
- package/docs/RELEASE-0.9.11.md +18 -0
- package/docs/RELEASE-0.9.12.md +9 -0
- package/docs/UNIFIED-HOME-1.5.4-ADOPTION.md +24 -0
- package/lib/client.js +43 -38
- package/package.json +4 -2
- package/docs/RELEASE-0.9.10.md +0 -24
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,21 @@
|
|
|
1
|
+
# 0.9.12 · 2026-09-14
|
|
2
|
+
|
|
3
|
+
- Remove home subtitle and its spacing, retain native controls.
|
|
4
|
+
- Keep launcher naming stable and prevent duplicate launches.
|
|
5
|
+
- Preserve other agents’ branding and surfaces; clarify recorded progress and synchronization failures.
|
|
6
|
+
- Adopt DSH-UX-001 v1.5.4; 277 checks and 10 isolated browser scenarios pass.
|
|
7
|
+
|
|
1
8
|
# Changelog
|
|
2
9
|
|
|
3
10
|
本文件记录 `dsh-data-cleaning-agent` 的版本变更。格式遵循 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/),版本号遵循 [SemVer](https://semver.org/lang/zh-CN/)。
|
|
4
11
|
|
|
5
12
|
## [Unreleased]
|
|
6
13
|
|
|
14
|
+
## [0.9.11] - 2026-09-13
|
|
15
|
+
|
|
16
|
+
- 修正真实 Host 首页判断:Session 并不提供 composerPhase;改为观察当前清洗会话 DOM 的真实 data-phase,确保标题替换实际启用。
|
|
17
|
+
- 回归夹具移除虚构 composerPhase 字段,覆盖 settling/hero/active、普通会话隔离与卸载恢复。
|
|
18
|
+
|
|
7
19
|
## [0.9.10] - 2026-09-13
|
|
8
20
|
|
|
9
21
|
- 修复首页先挂载于 settling 阶段导致 Logo 与标题替换被跳过的问题;监听宿主阶段及文本节点变化,显示“数据清洗补全智能体”。
|
package/README.en.md
CHANGED
|
@@ -10,7 +10,9 @@ Related agents: [数据清洗补全](https://github.com/duhu2000/dsh-data-cleani
|
|
|
10
10
|
|
|
11
11
|
> 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.
|
|
12
12
|
>
|
|
13
|
-
> Current source version / 当前源码版本: **0.9.
|
|
13
|
+
> Current source version / 当前源码版本: **0.9.12** (stable release)
|
|
14
|
+
|
|
15
|
+
0.9.12 removes the home subtitle and its spacing, keeps native workspace/mode/composer controls, prevents duplicate menu launches, and scopes branding to its own home. Task records are distinguished from live model activity. The 0.9.11 Host phase and Session restoration fixes remain intact.
|
|
14
16
|
|
|
15
17
|
0.9.10 observes the Host settling-to-hero transition so the database logo and product title appear even after delayed layout. Unknown structures do not trigger global headline rewriting. Rollback version: 0.9.9.
|
|
16
18
|
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
数据清洗补全智能体:面向 Excel/CSV/JSON 企业名单,提供数据清洗、表格清洗、清洗补全、去重、企业数据补全与字段补全,支持企查查 MCP 和结果导出。
|
|
10
10
|
|
|
11
11
|
```sh
|
|
12
|
-
dsh plugin --profile web add dsh-data-cleaning-agent@0.9.
|
|
12
|
+
dsh plugin --profile web add dsh-data-cleaning-agent@0.9.12
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
请先满足下文的 DSH、连接器及侧边栏依赖要求;安装后完整停止并重启对应 Profile。
|
|
@@ -27,7 +27,9 @@ dsh plugin --profile web add dsh-data-cleaning-agent@0.9.10
|
|
|
27
27
|
|
|
28
28
|
> 在 DeepSeek Harness 中清洗、补全、画像企业名单数据的智能体插件:本地 CSV/XLSX/JSON 引擎 + 可选企查查(Qichacha/QCC)MCP 企业数据补全,由企查查(Qichacha/QCC)团队发起并维护。
|
|
29
29
|
>
|
|
30
|
-
> 当前源码版本 / Current source version: **0.9.
|
|
30
|
+
> 当前源码版本 / Current source version: **0.9.12**(正式版本)
|
|
31
|
+
|
|
32
|
+
0.9.12 统一简洁首页:移除副标题与占位,保留原生工作区、模式和输入框。菜单名称固定并防止重复创建;品牌标题仅在所属首页生效,任务记录与模型运行状态明确区分。保留 0.9.11 的真实 Host 阶段与会话切换修复。
|
|
31
33
|
|
|
32
34
|
0.9.10 补齐首页 settling → hero 阶段监听,避免首次挂载漏掉 Logo 与标题替换;兼容“探索未知之境”,未知结构不做全局标题改写。回滚版本为 0.9.9。
|
|
33
35
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# 0.9.11 · Real Host home phase
|
|
2
|
+
|
|
3
|
+
The real DSH Session snapshot does not expose composerPhase. Versions 0.9.9/0.9.10
|
|
4
|
+
adapted the DOM rewrite but its caller never enabled it. The former React fixture
|
|
5
|
+
supplied that nonexistent property and masked the integration bug.
|
|
6
|
+
|
|
7
|
+
The cleaning experience now observes data-phase on its own marker's closest Host
|
|
8
|
+
root. It never derives the phase from input text or other Sessions. Unknown or active
|
|
9
|
+
roots are not treated as home. The observer disconnects on Session changes/unmount.
|
|
10
|
+
Hero changes retain the existing reversible logo/title behavior.
|
|
11
|
+
|
|
12
|
+
Session-scoped factories can also mount after the root ownership event. Restore
|
|
13
|
+
ownership from the explicit independently-created cleaning Session namespace;
|
|
14
|
+
never infer it from another Session, a task history selection or draft text.
|
|
15
|
+
|
|
16
|
+
Tests must omit composerPhase, cover settling/hero/active and ordinary Session cleanup.
|
|
17
|
+
Real logged-in DSH visual acceptance and final registry evidence are recorded in Release notes.
|
|
18
|
+
No paid QCC/OCR calls are needed for branding acceptance. Rollback: 0.9.10 (known title bug).
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# 0.9.12 · 简洁首页与局部品牌保护
|
|
2
|
+
|
|
3
|
+
首页移除副标题和专属留白,使用原生工作区、模式与输入框。左栏名称保持稳定,创建中禁用并阻止重复点击。品牌适配仅改写原生默认或本产品标题,停止隐藏其他产品 dock;保留 0.9.11 的真实阶段监听及晚挂载修复。
|
|
4
|
+
|
|
5
|
+
任务区说明任务记录不代表模型实时运行;同步失败保留记录且不重复查询。
|
|
6
|
+
|
|
7
|
+
验证:277 项检查,浅/深色 × 5 尺寸合成 Host React/Chromium 回归全部通过。未验证本轮真实四包共装、生产页面或真实计费 MCP。没有生产 Profile 修改。
|
|
8
|
+
|
|
9
|
+
发布要求:PR CI → 合并 main → main CI → 新 annotated v0.9.12 → 既有 OIDC workflow → Registry/provenance 回读。旧版本和 Tag 不动。
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# DSH-UX-001 v1.5.4 采用记录
|
|
2
|
+
|
|
3
|
+
日期:2026-09-14。基线:0.9.11 / a0ec971db0d25d42f67f99e4328cca6f49a2bc2f。
|
|
4
|
+
本轮仅本地代码与验收,不发布,不修改正式 Profile 或全局 DSH。
|
|
5
|
+
|
|
6
|
+
## 已采用
|
|
7
|
+
|
|
8
|
+
- UX-05:首页删除 ProductHome 副标题组件、挂载与 dcAgentHomeSummary 样式;没有替代空白容器。保留原生工作区/模式/输入控件以及输入框下能力菜单,不修改 npm description/搜索文案。
|
|
9
|
+
- UX-45:左菜单固定“数据清洗补全”;创建中通过 disabled/aria-busy 表示,ref 门闩阻止同一渲染周期重复创建。失败仍沿用已有工作台错误状态,菜单名称不变。
|
|
10
|
+
- UX-46:保留 0.9.11 的真实 data-phase、openState、所有权立即重读和独立 Session namespace。只接管原生已知 Hero 标题或本插件标记;不覆盖其他产品标题,不再隐藏其他产品 dock。清理仅恢复仍为本插件标题的文字,不调用会话 rename API。
|
|
11
|
+
- UX-47:任务区明确展示“任务记录”,匹配/补全记录不冒充模型实时运行证明;元数据恢复/轮询失败明确为“状态同步异常”,保留最后记录且不重新查询。已有确认、取消、失败、完成状态继续来自 Host 任务数据,实际主体进度仍来自服务端计数,不伪造百分比。
|
|
12
|
+
|
|
13
|
+
## 验证范围
|
|
14
|
+
|
|
15
|
+
- npm run check:277 项通过,包括安装包检查、正文语法与既有业务测试。
|
|
16
|
+
- 新增/调整断言:首页不含副标题组件或专属样式;同时点击只创建一个 Session;外产品标题和 dock 不被接管;既有 settling→hero、文本刷新、普通 Session、phase observer 清理继续回归。
|
|
17
|
+
- scripts/ui-layout-regression.mjs:10/10 通过,真实 React/Chromium,合成 Host DOM/API fixture,浅/深色 × 5 尺寸。验证品牌、普通会话恢复、晚挂载和无副标题;完整现有导入/映射/确认/下载测试保留。
|
|
18
|
+
- 浏览器 fixture 不等于完整真实 DSH 宿主。当前本轮未验证四包真实共装、用户正式页面或真实模型/QCC/OCR;正式版本仍为 0.9.11。
|
|
19
|
+
|
|
20
|
+
## 边界
|
|
21
|
+
|
|
22
|
+
清洗目前没有已验证的模型 running 状态接口,不新增假定宿主正在思考的状态条,也不声称掌握模型停止原因。恢复仅读取任务元数据。模型运行态由原生会话显示。
|
|
23
|
+
|
|
24
|
+
证据:`/private/tmp/dc-unified-home-check.log`、`/private/tmp/dc-unified-home-ui-final.log` 与本工作树 `_scratch/ui-layout/results.json`。最后的未知标题保护收紧由观察器行为测试覆盖,未影响布局;其后完整 277 项检查再次通过。
|
package/lib/client.js
CHANGED
|
@@ -200,14 +200,13 @@ window.__ModuleLoader__.load({
|
|
|
200
200
|
}
|
|
201
201
|
.dcAgentCapability svg { flex: 0 0 auto; }
|
|
202
202
|
|
|
203
|
-
/*
|
|
203
|
+
/* 首页无副标题或占位;菜单独立 Portal 到 composer 后,不重排共享 slot。 */
|
|
204
204
|
|
|
205
205
|
.dcAgentExperience {
|
|
206
206
|
width: 100%;
|
|
207
207
|
box-sizing: border-box;
|
|
208
208
|
}
|
|
209
209
|
.dcAgentCapabilityMount { width: 100%; padding: 8px 0; flex: none; }
|
|
210
|
-
.dcAgentHomeSummary { margin: 0 20px 8px; text-align: center; color: var(--dc-muted); font-size: 13px; line-height: 20px; }
|
|
211
210
|
.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; }
|
|
212
211
|
body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
213
212
|
|
|
@@ -1530,6 +1529,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
1530
1529
|
isCleaningSession(sessionId) ? sessionId : null,
|
|
1531
1530
|
);
|
|
1532
1531
|
react.useEffect(() => {
|
|
1532
|
+
setMarkedSessionId(isCleaningSession(sessionId) ? sessionId : null);
|
|
1533
1533
|
const handleMarked = (event) => {
|
|
1534
1534
|
const detail = event?.detail ?? {};
|
|
1535
1535
|
setMarkedSessionId(detail.active === true && detail.sessionId === sessionId ? sessionId : null);
|
|
@@ -1539,7 +1539,9 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
1539
1539
|
}, [sessionId]);
|
|
1540
1540
|
// DSH 可能复用同一个 slot component 切换会话;状态必须绑定具体 sessionId,
|
|
1541
1541
|
// 避免从清洗会话切回普通会话后仍残留业务首页与提示词入口。
|
|
1542
|
-
|
|
1542
|
+
// Session-scoped slot factories can mount after the root ownership event.
|
|
1543
|
+
// Our independently-created namespace is durable ownership, unlike a draft.
|
|
1544
|
+
return ownedSessionId(sessionId) || (markedSessionId === sessionId && isCleaningSession(sessionId));
|
|
1543
1545
|
}
|
|
1544
1546
|
|
|
1545
1547
|
/**
|
|
@@ -2528,6 +2530,8 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
2528
2530
|
const { wide, useStore, actions, startSession } = props;
|
|
2529
2531
|
useStore((state) => state.open);
|
|
2530
2532
|
const [topMount, setTopMount] = react.useState(null);
|
|
2533
|
+
const [opening, setOpening] = react.useState(false);
|
|
2534
|
+
const openingRef = react.useRef(false);
|
|
2531
2535
|
|
|
2532
2536
|
react.useEffect(() => {
|
|
2533
2537
|
let disposed = false;
|
|
@@ -2556,7 +2560,12 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
2556
2560
|
className: 'dcAgentLauncher',
|
|
2557
2561
|
'data-wide': wide,
|
|
2558
2562
|
'aria-label': '数据清洗补全',
|
|
2563
|
+
'aria-busy': opening,
|
|
2564
|
+
disabled: opening,
|
|
2559
2565
|
onClick: async () => {
|
|
2566
|
+
if (openingRef.current) return;
|
|
2567
|
+
openingRef.current = true;
|
|
2568
|
+
setOpening(true);
|
|
2560
2569
|
try {
|
|
2561
2570
|
if (typeof startSession === 'function') {
|
|
2562
2571
|
const sessionId = await startSession();
|
|
@@ -2565,6 +2574,9 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
2565
2574
|
} catch (error) {
|
|
2566
2575
|
actions.setError(error instanceof Error ? error.message : String(error));
|
|
2567
2576
|
console.error('[dc-agent] open failed:', error);
|
|
2577
|
+
} finally {
|
|
2578
|
+
openingRef.current = false;
|
|
2579
|
+
setOpening(false);
|
|
2568
2580
|
}
|
|
2569
2581
|
},
|
|
2570
2582
|
children: h('span', { className: 'dcAgentLauncherContent' }, h(DatabaseLogo), wide ? h('span', null, '数据清洗补全') : null),
|
|
@@ -2601,11 +2613,6 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
2601
2613
|
authorization_required: '待连接企查查', cancelled: '已取消', parse_failed: '解析失败',
|
|
2602
2614
|
};
|
|
2603
2615
|
|
|
2604
|
-
function ProductHome() {
|
|
2605
|
-
return h('p', { className: 'dcAgentHomeSummary' },
|
|
2606
|
-
'导入企业名单或图片,核验主体、补全字段,并导出可追溯结果。');
|
|
2607
|
-
}
|
|
2608
|
-
|
|
2609
2616
|
function workflowNavigationIssue(step, task, hasData, profile, qccRun, hasLocalResult = false) {
|
|
2610
2617
|
if (['upload', 'history'].includes(step)) return null;
|
|
2611
2618
|
if (step === 'download' && task?.artifacts?.length) return null;
|
|
@@ -2741,9 +2748,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
2741
2748
|
const changedMarks = new Map();
|
|
2742
2749
|
const changedRows = new Map();
|
|
2743
2750
|
const ownedLogos = new Map();
|
|
2744
|
-
|
|
2745
|
-
const composerStack = marker?.parentElement?.parentElement;
|
|
2746
|
-
// 单一会话所有权由入口的 enabled 参数(useCleaningSession(sessionId) && composerPhase==='blank')
|
|
2751
|
+
// 单一会话所有权由入口 enabled 与真实宿主 data-phase=hero 共同保证,
|
|
2747
2752
|
// 与 React effect 生命周期共同保证:非清洗会话不会挂载,会话切换即走 cleanup 让位。
|
|
2748
2753
|
// 有界同步:每次 fix 的 DOM 变更计入校正预算,达到上限即断开观察器,杜绝与其它插件互相改写的死循环。
|
|
2749
2754
|
const MAX_HERO_CORRECTIONS = 8;
|
|
@@ -2760,7 +2765,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
2760
2765
|
?? hero.querySelector?.('[class*="headlineText"]');
|
|
2761
2766
|
const badge = spans.find((element) => element.dataset?.dcAgentHeroBadge === 'true')
|
|
2762
2767
|
?? spans.find((element) => ['预览版', 'Preview'].includes(element.textContent?.trim()));
|
|
2763
|
-
if (title) {
|
|
2768
|
+
if (title && ['数据清洗补全智能体', '探索未至之境', '探索未知之境', 'Into the Unknown'].includes(title.textContent?.trim())) {
|
|
2764
2769
|
if (!changedTitles.has(title)) changedTitles.set(title, title.textContent ?? '');
|
|
2765
2770
|
title.dataset.dcAgentHeroTitle = 'true';
|
|
2766
2771
|
if (title.textContent !== '数据清洗补全智能体') { title.textContent = '数据清洗补全智能体'; mutated = true; }
|
|
@@ -2788,28 +2793,12 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
2788
2793
|
}
|
|
2789
2794
|
}
|
|
2790
2795
|
}
|
|
2791
|
-
if (badge) {
|
|
2796
|
+
if (badge && title?.dataset?.dcAgentHeroTitle === 'true') {
|
|
2792
2797
|
if (!changedBadges.has(badge)) changedBadges.set(badge, badge.style?.display ?? '');
|
|
2793
2798
|
badge.dataset.dcAgentHeroBadge = 'true';
|
|
2794
2799
|
if (badge.style && badge.style.display !== 'none') { badge.style.display = 'none'; mutated = true; }
|
|
2795
2800
|
}
|
|
2796
2801
|
|
|
2797
|
-
const foreignSurfaces = composerStack?.querySelectorAll?.('[aria-label="尽调类型"], .qccDock') ?? [];
|
|
2798
|
-
for (const foreignSurface of foreignSurfaces) {
|
|
2799
|
-
let hideTarget = foreignSurface;
|
|
2800
|
-
while (hideTarget?.parentElement
|
|
2801
|
-
&& hideTarget.parentElement !== composerStack
|
|
2802
|
-
&& hideTarget.parentElement !== marker.parentElement) {
|
|
2803
|
-
hideTarget = hideTarget.parentElement;
|
|
2804
|
-
}
|
|
2805
|
-
// DSH 的 list slot 可能把多个插件放进同一个 data-slot 容器。此时只能隐藏
|
|
2806
|
-
// 对方自己的根节点,不能隐藏共享 slot;独立 host 则隐藏其直接容器。
|
|
2807
|
-
if ((hideTarget?.parentElement === composerStack || hideTarget?.parentElement === marker.parentElement)
|
|
2808
|
-
&& !hideTarget.contains?.(marker)) {
|
|
2809
|
-
if (!hiddenForeignDocks.has(hideTarget)) hiddenForeignDocks.set(hideTarget, hideTarget.style?.display ?? '');
|
|
2810
|
-
if (hideTarget.style && hideTarget.style.display !== 'none') { hideTarget.style.display = 'none'; mutated = true; }
|
|
2811
|
-
}
|
|
2812
|
-
}
|
|
2813
2802
|
if (mutated) {
|
|
2814
2803
|
corrections += 1;
|
|
2815
2804
|
if (corrections >= MAX_HERO_CORRECTIONS && observer) {
|
|
@@ -2839,12 +2828,25 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
2839
2828
|
if (badge.style) badge.style.display = originalDisplay;
|
|
2840
2829
|
delete badge.dataset.dcAgentHeroBadge;
|
|
2841
2830
|
}
|
|
2842
|
-
for (const [foreignDock, originalDisplay] of hiddenForeignDocks) {
|
|
2843
|
-
if (foreignDock.style) foreignDock.style.display = originalDisplay;
|
|
2844
|
-
}
|
|
2845
2831
|
};
|
|
2846
2832
|
}
|
|
2847
2833
|
|
|
2834
|
+
function observeHomePhase(sessionId, enabled, onChange) {
|
|
2835
|
+
onChange(false);
|
|
2836
|
+
if (!enabled || typeof document === 'undefined') return () => {};
|
|
2837
|
+
const marker = [...(document.querySelectorAll?.('.dcAgentExperience') || [])]
|
|
2838
|
+
.find(node => node.dataset?.sessionId === sessionId);
|
|
2839
|
+
// Session snapshots do not expose composerPhase. The Host's own rendered root
|
|
2840
|
+
// is authoritative; never infer a blank conversation from draft text or title.
|
|
2841
|
+
const root = marker?.closest?.('[data-phase]');
|
|
2842
|
+
if (!root) return () => {};
|
|
2843
|
+
const update = () => onChange(root.getAttribute('data-phase') === 'hero');
|
|
2844
|
+
update();
|
|
2845
|
+
const observer = typeof MutationObserver === 'function' ? new MutationObserver(update) : null;
|
|
2846
|
+
observer?.observe(root, { attributes: true, attributeFilter: ['data-phase'] });
|
|
2847
|
+
return () => observer?.disconnect();
|
|
2848
|
+
}
|
|
2849
|
+
|
|
2848
2850
|
function DataCleaningExperience(props) {
|
|
2849
2851
|
const { sessionId, session: ownerSession } = props;
|
|
2850
2852
|
const enabled = useCleaningSession(sessionId);
|
|
@@ -2854,7 +2856,10 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
2854
2856
|
document.addEventListener(DEPENDENCY_EVENT, listener);
|
|
2855
2857
|
return () => document.removeEventListener(DEPENDENCY_EVENT, listener);
|
|
2856
2858
|
}, [sessionId]);
|
|
2857
|
-
const hero =
|
|
2859
|
+
const [hero, setHero] = react.useState(false);
|
|
2860
|
+
react.useEffect(() => observeHomePhase(sessionId, enabled,
|
|
2861
|
+
value => setHero(current => current === value ? current : value)),
|
|
2862
|
+
[sessionId, enabled, ownerSession?.openState]);
|
|
2858
2863
|
const [menuMount, setMenuMount] = react.useState(null);
|
|
2859
2864
|
react.useEffect(() => {
|
|
2860
2865
|
if (!enabled) return undefined;
|
|
@@ -2873,7 +2878,6 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
2873
2878
|
},
|
|
2874
2879
|
dependencyMessage ? h('p', { className: 'dcAgentError', role: 'alert' }, dependencyMessage) : null,
|
|
2875
2880
|
menuMount ? reactDom.createPortal(h(CapabilityBar, { sessionId }), menuMount) : h(CapabilityBar, { sessionId }),
|
|
2876
|
-
hero ? h(ProductHome, { sessionId }) : null,
|
|
2877
2881
|
);
|
|
2878
2882
|
}
|
|
2879
2883
|
|
|
@@ -3850,7 +3854,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
3850
3854
|
const taskId = workflowTaskBySession.get(key)?.id || (/^dcw-[a-zA-Z0-9-]+$/.test(saved || '') ? saved : null);
|
|
3851
3855
|
if (taskId) await refreshHostedTask(actions, activeSessionId, taskId, null, false);
|
|
3852
3856
|
}).catch((taskError) => {
|
|
3853
|
-
if (!disposed) actions.setError(taskError instanceof Error ? taskError.message : String(taskError));
|
|
3857
|
+
if (!disposed) actions.setError(`状态同步异常:${taskError instanceof Error ? taskError.message : String(taskError)}。保留最近任务记录,未重新执行查询。`);
|
|
3854
3858
|
});
|
|
3855
3859
|
}
|
|
3856
3860
|
return () => { disposed = true; };
|
|
@@ -3868,7 +3872,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
3868
3872
|
if (!task) return;
|
|
3869
3873
|
if (['matching', 'enriching'].includes(task.state)) timer = setTimeout(poll, 2000);
|
|
3870
3874
|
else if (step === 'match' || step === 'enrich') actions.setStep(task.stage || step);
|
|
3871
|
-
} catch (error) { if (!disposed) actions.setError(error.message); }
|
|
3875
|
+
} catch (error) { if (!disposed) actions.setError(`状态同步异常:${error.message}。保留最近任务记录,未重新执行查询。`); }
|
|
3872
3876
|
};
|
|
3873
3877
|
timer = setTimeout(poll, 2000);
|
|
3874
3878
|
return () => { disposed = true; clearTimeout(timer); };
|
|
@@ -4809,8 +4813,9 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
4809
4813
|
) : null,
|
|
4810
4814
|
h('div', { className: 'dcAgentWbBody' },
|
|
4811
4815
|
cachedTask && step !== 'history' ? h('section', { className: 'dcAgentSection', 'aria-label': '当前任务进展', 'aria-live': 'polite' },
|
|
4812
|
-
h('b', null, cachedTask.source?.type === 'image' && cachedTask.state === 'draft' ? '图片已暂存,待识别' : WORKFLOW_STATE_LABELS[cachedTask.state] ||
|
|
4816
|
+
h('b', null, cachedTask.source?.type === 'image' && cachedTask.state === 'draft' ? '图片已暂存,待识别' : `任务记录:${WORKFLOW_STATE_LABELS[cachedTask.state] || '状态未知'}`),
|
|
4813
4817
|
h('h3', null, workflowDisplayName(cachedTask)),
|
|
4818
|
+
['matching', 'enriching'].includes(cachedTask.state) ? h('p', { className: 'dcAgentHint' }, '以上为最近同步的任务记录,不代表模型仍在运行。若会话已停止,请查看原会话的确认或错误提示;不要重复启动。') : null,
|
|
4814
4819
|
h('details', null, h('summary', null, '任务详情'), h('p', { className: 'dcAgentHint' }, `任务编号:${cachedTask.id}`)),
|
|
4815
4820
|
h('p', null, `${cachedTask.source?.type === 'image' ? '图片识别' : cachedTask.source?.type === 'text' ? '粘贴名单' : cachedTask.source ? '上传表格' : '待选择数据来源'}${cachedTask.source?.fileName ? ' · ' + cachedTask.source.fileName : ''} · ${cachedTask.source?.type === 'image' && cachedTask.state === 'draft' ? '条目数待识别' : `${cachedTask.source?.rowCount || 0} 条`} · ${cachedTask.fieldSelection?.length || 0} 个补全字段`),
|
|
4816
4821
|
commandProgress?.taskId === cachedTask.id && Number.isFinite(commandProgress.totalUnique) ? h('p', null, `已处理主体 ${commandProgress.completedUnique}/${commandProgress.totalUnique}(去重后,含未匹配或失败,不代表补全成功)`) : null,
|
|
@@ -5217,7 +5222,6 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
5217
5222
|
visibleCatalogFields,
|
|
5218
5223
|
installCapabilityMount,
|
|
5219
5224
|
PromptDialog,
|
|
5220
|
-
ProductHome,
|
|
5221
5225
|
workflowNavigationIssue,
|
|
5222
5226
|
buildTaskPrompt,
|
|
5223
5227
|
DatasetReview,
|
|
@@ -5248,6 +5252,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
5248
5252
|
plainEntityListDataset,
|
|
5249
5253
|
resultFieldLabel,
|
|
5250
5254
|
rewriteHeroChrome,
|
|
5255
|
+
observeHomePhase,
|
|
5251
5256
|
ensureWorkflowTask,
|
|
5252
5257
|
ensureEditableWorkflowTask,
|
|
5253
5258
|
queueWorkflowOperation,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-data-cleaning-agent",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.12",
|
|
4
4
|
"description": "Data cleaning and data enrichment for CSV/XLSX/JSON enterprise lists in DeepSeek Harness, including spreadsheet cleaning, deduplication, profiling, optional Qichacha MCP and exports.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -20,7 +20,9 @@
|
|
|
20
20
|
"install.sh",
|
|
21
21
|
"marketing",
|
|
22
22
|
"docs/USER-GUIDE.md",
|
|
23
|
-
"docs/RELEASE-0.9.
|
|
23
|
+
"docs/RELEASE-0.9.11.md",
|
|
24
|
+
"docs/RELEASE-0.9.12.md",
|
|
25
|
+
"docs/UNIFIED-HOME-1.5.4-ADOPTION.md",
|
|
24
26
|
"docs/FIRST-CONTRIBUTION.md",
|
|
25
27
|
"docs/COMPATIBILITY.md",
|
|
26
28
|
"docs/UI-V1.5.0-ADOPTION.md",
|
package/docs/RELEASE-0.9.10.md
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
# 0.9.10 · Delayed home branding
|
|
2
|
-
|
|
3
|
-
## Scope
|
|
4
|
-
|
|
5
|
-
Preserves 0.9.9 sibling-branch compatibility and 0.9.8 Session ownership. Adds observation
|
|
6
|
-
of Host settling-to-hero layout transitions and headline text-node updates. The home displays
|
|
7
|
-
the blue database logo plus “数据清洗补全智能体”. Both Chinese Host headline variants work.
|
|
8
|
-
Unknown layout never falls back to rewriting document.body. Cleanup restores native branding.
|
|
9
|
-
|
|
10
|
-
## Verification and boundary
|
|
11
|
-
|
|
12
|
-
Node regression covers delayed mounting, text refresh, reversible cleanup and ordinary-session
|
|
13
|
-
isolation. Real React/Chromium matrix exercises settling-to-hero before checking logo placement,
|
|
14
|
-
light/dark responsive layouts and active/ordinary Session transitions. Existing workflow tests
|
|
15
|
-
remain mandatory. Run npm run check and npm run test:ui before release.
|
|
16
|
-
|
|
17
|
-
The live localhost DSH tab still requires authentication; no live-host success is claimed.
|
|
18
|
-
After upgrading/restarting, click 数据清洗补全, confirm logo/title, then switch to an ordinary
|
|
19
|
-
Session and confirm native branding. No paid MCP, OCR or production data is used in tests.
|
|
20
|
-
|
|
21
|
-
## Publishing
|
|
22
|
-
|
|
23
|
-
Use PR/main CI gates before annotated v0.9.10, existing GitHub OIDC/provenance workflow,
|
|
24
|
-
then registry version/gitHead and tarball read-back. Rollback: 0.9.9 (may miss delayed hero).
|