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 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.10** (stable release)
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.10
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.10**(正式版本)
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
- /* 原生 input.dock 保留轻量简介;菜单独立 Portal 到 composer 后,不重排共享 slot。 */
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
- return markedSessionId === sessionId && isCleaningSession(sessionId);
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
- const hiddenForeignDocks = new Map();
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 = ownerSession?.composerPhase === 'blank';
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] || 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.10",
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.10.md",
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",
@@ -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).