dsh-data-cleaning-agent 0.9.9 → 0.9.11
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 +11 -0
- package/README.en.md +5 -1
- package/README.md +6 -2
- package/docs/RELEASE-0.9.11.md +18 -0
- package/lib/client.js +37 -10
- package/package.json +2 -2
- package/docs/RELEASE-0.9.9.md +0 -24
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,17 @@
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.9.11] - 2026-09-13
|
|
8
|
+
|
|
9
|
+
- 修正真实 Host 首页判断:Session 并不提供 composerPhase;改为观察当前清洗会话 DOM 的真实 data-phase,确保标题替换实际启用。
|
|
10
|
+
- 回归夹具移除虚构 composerPhase 字段,覆盖 settling/hero/active、普通会话隔离与卸载恢复。
|
|
11
|
+
|
|
12
|
+
## [0.9.10] - 2026-09-13
|
|
13
|
+
|
|
14
|
+
- 修复首页先挂载于 settling 阶段导致 Logo 与标题替换被跳过的问题;监听宿主阶段及文本节点变化,显示“数据清洗补全智能体”。
|
|
15
|
+
- 兼容“探索未知之境”文案,保留 0.9.9 同级标题分支适配;不再降级到 document.body 全局改写。
|
|
16
|
+
- 新增延迟 Hero 挂载、标题刷新和离开会话恢复回归;真实 DSH 页面仍需登录后验收。
|
|
17
|
+
|
|
7
18
|
## [0.9.9] - 2026-09-13
|
|
8
19
|
|
|
9
20
|
- 原生首页标题桥接适配新版 Host 的 composer sibling slot;菜单进入数据清洗补全后稳定显示“数据清洗补全智能体”,不再回退为“探索未至之境”。
|
package/README.en.md
CHANGED
|
@@ -10,7 +10,11 @@ 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.11** (stable release)
|
|
14
|
+
|
|
15
|
+
0.9.11 uses the current cleaning Session's rendered Host phase instead of the nonexistent Session.composerPhase property. Branding appears on the real home screen and restores when leaving it.
|
|
16
|
+
|
|
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.
|
|
14
18
|
|
|
15
19
|
0.9.9 restores the “数据清洗补全智能体” native home title when newer Host builds place the plugin marker and Hero headline in sibling composer branches. The bridge remains reversible and isolated from other business plugins. The 0.9.8 read-only Profile history and origin Workspace/Session guarantees remain unchanged. Rollback: `dsh plugin --profile web add dsh-data-cleaning-agent@0.9.8`. Live DSH A/B verification remains a post-install user check.
|
|
16
20
|
|
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.11
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
请先满足下文的 DSH、连接器及侧边栏依赖要求;安装后完整停止并重启对应 Profile。
|
|
@@ -27,7 +27,11 @@ dsh plugin --profile web add dsh-data-cleaning-agent@0.9.9
|
|
|
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.11**(正式版本)
|
|
31
|
+
|
|
32
|
+
0.9.11 修正真实 Host 的首页状态接口:不再依赖 Session.composerPhase,按当前清洗会话所在宿主根节点的 data-phase 显示 Logo 与标题,并在离开首页时恢复。
|
|
33
|
+
|
|
34
|
+
0.9.10 补齐首页 settling → hero 阶段监听,避免首次挂载漏掉 Logo 与标题替换;兼容“探索未知之境”,未知结构不做全局标题改写。回滚版本为 0.9.9。
|
|
31
35
|
|
|
32
36
|
0.9.9 修复新版 Host composer sibling slot 下的原生首页标题定位,进入数据清洗补全后稳定显示“数据清洗补全智能体”,并保持对其它业务插件的标题隔离。0.9.8 的 Profile 历史只读、来源工作区/会话校验与旧记录边界全部保留。回滚:`dsh plugin --profile web add dsh-data-cleaning-agent@0.9.8`。真实 DSH A/B 验收仍以安装后的用户验证为准,详见发布说明。
|
|
33
37
|
|
|
@@ -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).
|
package/lib/client.js
CHANGED
|
@@ -1530,6 +1530,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
1530
1530
|
isCleaningSession(sessionId) ? sessionId : null,
|
|
1531
1531
|
);
|
|
1532
1532
|
react.useEffect(() => {
|
|
1533
|
+
setMarkedSessionId(isCleaningSession(sessionId) ? sessionId : null);
|
|
1533
1534
|
const handleMarked = (event) => {
|
|
1534
1535
|
const detail = event?.detail ?? {};
|
|
1535
1536
|
setMarkedSessionId(detail.active === true && detail.sessionId === sessionId ? sessionId : null);
|
|
@@ -1539,7 +1540,9 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
1539
1540
|
}, [sessionId]);
|
|
1540
1541
|
// DSH 可能复用同一个 slot component 切换会话;状态必须绑定具体 sessionId,
|
|
1541
1542
|
// 避免从清洗会话切回普通会话后仍残留业务首页与提示词入口。
|
|
1542
|
-
|
|
1543
|
+
// Session-scoped slot factories can mount after the root ownership event.
|
|
1544
|
+
// Our independently-created namespace is durable ownership, unlike a draft.
|
|
1545
|
+
return ownedSessionId(sessionId) || (markedSessionId === sessionId && isCleaningSession(sessionId));
|
|
1543
1546
|
}
|
|
1544
1547
|
|
|
1545
1548
|
/**
|
|
@@ -2722,18 +2725,19 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
2722
2725
|
if (!scope?.querySelectorAll) return false;
|
|
2723
2726
|
const spans = [...scope.querySelectorAll('span')];
|
|
2724
2727
|
return spans.some((element) => element.dataset?.dcAgentHeroTitle === 'true'
|
|
2725
|
-
|| ['探索未至之境', 'Into the Unknown'].includes(element.textContent?.trim()))
|
|
2728
|
+
|| ['探索未至之境', '探索未知之境', 'Into the Unknown'].includes(element.textContent?.trim()))
|
|
2726
2729
|
|| Boolean(scope.querySelector?.('[class*="headlineText"]'));
|
|
2727
2730
|
};
|
|
2728
2731
|
// 新版 Host 会把 list slot 放在 composer seat 的独立分支;marker 不一定再是
|
|
2729
2732
|
// data-phase=hero 的后代。沿祖先寻找同时包含原生标题的最小范围,保留旧结构兼容。
|
|
2730
|
-
|
|
2733
|
+
// Observe the same root while Host layout transitions from settling to hero.
|
|
2734
|
+
let hero = marker?.closest?.('[data-phase="hero"]')
|
|
2735
|
+
?? marker?.closest?.('[data-phase="settling"]') ?? null;
|
|
2731
2736
|
if (!hasHeadline(hero)) {
|
|
2732
2737
|
let scope = marker?.closest?.('[data-composer-seat]') ?? marker?.parentElement ?? null;
|
|
2733
|
-
while (scope && !hasHeadline(scope)) scope = scope.parentElement;
|
|
2734
|
-
if (scope) hero = scope;
|
|
2738
|
+
while (scope && scope !== document.body && scope !== document.documentElement && !hasHeadline(scope)) scope = scope.parentElement;
|
|
2739
|
+
if (scope && scope !== document.body && scope !== document.documentElement) hero = scope;
|
|
2735
2740
|
}
|
|
2736
|
-
if (!hero && document.body?.querySelectorAll) hero = document.body;
|
|
2737
2741
|
if (!hero) return () => {};
|
|
2738
2742
|
const changedTitles = new Map();
|
|
2739
2743
|
const changedBadges = new Map();
|
|
@@ -2742,7 +2746,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
2742
2746
|
const ownedLogos = new Map();
|
|
2743
2747
|
const hiddenForeignDocks = new Map();
|
|
2744
2748
|
const composerStack = marker?.parentElement?.parentElement;
|
|
2745
|
-
//
|
|
2749
|
+
// 单一会话所有权由入口 enabled 与真实宿主 data-phase=hero 共同保证,
|
|
2746
2750
|
// 与 React effect 生命周期共同保证:非清洗会话不会挂载,会话切换即走 cleanup 让位。
|
|
2747
2751
|
// 有界同步:每次 fix 的 DOM 变更计入校正预算,达到上限即断开观察器,杜绝与其它插件互相改写的死循环。
|
|
2748
2752
|
const MAX_HERO_CORRECTIONS = 8;
|
|
@@ -2750,10 +2754,12 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
2750
2754
|
let observer = null;
|
|
2751
2755
|
|
|
2752
2756
|
const fix = () => {
|
|
2757
|
+
if (hero.getAttribute?.('data-phase') === 'settling') return;
|
|
2758
|
+
if (hero.getAttribute?.('data-phase') === 'active') return;
|
|
2753
2759
|
let mutated = false;
|
|
2754
2760
|
const spans = [...hero.querySelectorAll('span')];
|
|
2755
2761
|
const title = spans.find((element) => element.dataset?.dcAgentHeroTitle === 'true')
|
|
2756
|
-
?? spans.find((element) => ['探索未至之境', 'Into the Unknown'].includes(element.textContent?.trim()))
|
|
2762
|
+
?? spans.find((element) => ['探索未至之境', '探索未知之境', 'Into the Unknown'].includes(element.textContent?.trim()))
|
|
2757
2763
|
?? hero.querySelector?.('[class*="headlineText"]');
|
|
2758
2764
|
const badge = spans.find((element) => element.dataset?.dcAgentHeroBadge === 'true')
|
|
2759
2765
|
?? spans.find((element) => ['预览版', 'Preview'].includes(element.textContent?.trim()));
|
|
@@ -2818,7 +2824,8 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
2818
2824
|
|
|
2819
2825
|
fix();
|
|
2820
2826
|
observer = typeof MutationObserver === 'function' ? new MutationObserver(fix) : null;
|
|
2821
|
-
observer?.observe?.(hero, { childList: true, subtree: true
|
|
2827
|
+
observer?.observe?.(hero, { childList: true, subtree: true, characterData: true,
|
|
2828
|
+
attributes: true, attributeFilter: ['data-phase'] });
|
|
2822
2829
|
return () => {
|
|
2823
2830
|
observer?.disconnect?.();
|
|
2824
2831
|
for (const logo of ownedLogos.values()) logo.remove();
|
|
@@ -2841,6 +2848,22 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
2841
2848
|
};
|
|
2842
2849
|
}
|
|
2843
2850
|
|
|
2851
|
+
function observeHomePhase(sessionId, enabled, onChange) {
|
|
2852
|
+
onChange(false);
|
|
2853
|
+
if (!enabled || typeof document === 'undefined') return () => {};
|
|
2854
|
+
const marker = [...(document.querySelectorAll?.('.dcAgentExperience') || [])]
|
|
2855
|
+
.find(node => node.dataset?.sessionId === sessionId);
|
|
2856
|
+
// Session snapshots do not expose composerPhase. The Host's own rendered root
|
|
2857
|
+
// is authoritative; never infer a blank conversation from draft text or title.
|
|
2858
|
+
const root = marker?.closest?.('[data-phase]');
|
|
2859
|
+
if (!root) return () => {};
|
|
2860
|
+
const update = () => onChange(root.getAttribute('data-phase') === 'hero');
|
|
2861
|
+
update();
|
|
2862
|
+
const observer = typeof MutationObserver === 'function' ? new MutationObserver(update) : null;
|
|
2863
|
+
observer?.observe(root, { attributes: true, attributeFilter: ['data-phase'] });
|
|
2864
|
+
return () => observer?.disconnect();
|
|
2865
|
+
}
|
|
2866
|
+
|
|
2844
2867
|
function DataCleaningExperience(props) {
|
|
2845
2868
|
const { sessionId, session: ownerSession } = props;
|
|
2846
2869
|
const enabled = useCleaningSession(sessionId);
|
|
@@ -2850,7 +2873,10 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
2850
2873
|
document.addEventListener(DEPENDENCY_EVENT, listener);
|
|
2851
2874
|
return () => document.removeEventListener(DEPENDENCY_EVENT, listener);
|
|
2852
2875
|
}, [sessionId]);
|
|
2853
|
-
const hero =
|
|
2876
|
+
const [hero, setHero] = react.useState(false);
|
|
2877
|
+
react.useEffect(() => observeHomePhase(sessionId, enabled,
|
|
2878
|
+
value => setHero(current => current === value ? current : value)),
|
|
2879
|
+
[sessionId, enabled, ownerSession?.openState]);
|
|
2854
2880
|
const [menuMount, setMenuMount] = react.useState(null);
|
|
2855
2881
|
react.useEffect(() => {
|
|
2856
2882
|
if (!enabled) return undefined;
|
|
@@ -5244,6 +5270,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
5244
5270
|
plainEntityListDataset,
|
|
5245
5271
|
resultFieldLabel,
|
|
5246
5272
|
rewriteHeroChrome,
|
|
5273
|
+
observeHomePhase,
|
|
5247
5274
|
ensureWorkflowTask,
|
|
5248
5275
|
ensureEditableWorkflowTask,
|
|
5249
5276
|
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.11",
|
|
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,7 @@
|
|
|
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
24
|
"docs/FIRST-CONTRIBUTION.md",
|
|
25
25
|
"docs/COMPATIBILITY.md",
|
|
26
26
|
"docs/UI-V1.5.0-ADOPTION.md",
|
package/docs/RELEASE-0.9.9.md
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
# 0.9.9 · Native home title compatibility
|
|
2
|
-
|
|
3
|
-
Status: stable release. Date: 2026-09-13.
|
|
4
|
-
|
|
5
|
-
## Scope
|
|
6
|
-
|
|
7
|
-
- Adapt the reversible native Hero title bridge to Host layouts where the plugin marker and headline live in sibling branches below the composer container.
|
|
8
|
-
- Keep the data-cleaning home title fixed at “数据清洗补全智能体” without modifying another business plugin's headline, prompt UI or input focus.
|
|
9
|
-
- Preserve the 0.9.8 Profile history ownership, origin Workspace/Session checks and artifact-download behavior.
|
|
10
|
-
|
|
11
|
-
## Verification
|
|
12
|
-
|
|
13
|
-
- The coexistence fixture now exercises a sibling-slot Host structure rather than the obsolete nested Hero structure.
|
|
14
|
-
- `npm run check` covers syntax, documentation version consistency, marketing metadata, package allowlist and the full Node test suite.
|
|
15
|
-
- The React/Chromium layout matrix remains a separate isolated UI gate; real DSH and production QCC Provider behavior require post-install acceptance.
|
|
16
|
-
|
|
17
|
-
## Install and rollback
|
|
18
|
-
|
|
19
|
-
```sh
|
|
20
|
-
dsh plugin --profile web add dsh-data-cleaning-agent@0.9.9
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
Rollback package: `dsh plugin --profile web add dsh-data-cleaning-agent@0.9.8`.
|
|
24
|
-
Do not move or overwrite existing tags or npm versions.
|