dsh-data-cleaning-agent 0.8.21 → 0.8.22
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 +8 -0
- package/README.en.md +1 -1
- package/README.md +3 -3
- package/docs/RELEASE-0.8.22.md +11 -0
- package/lib/client.js +50 -7
- package/lib/qcc.js +5 -1
- package/package.json +2 -2
- package/docs/RELEASE-0.8.21.md +0 -9
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.8.22] - 2026-09-09
|
|
8
|
+
|
|
9
|
+
- 表格预览保留可读列宽、横向滚动和固定表头,避免多列挤压成竖排。
|
|
10
|
+
- 结果文件操作分行并留白,长文件名换行;失败计数单独展示,避免零补全被标绿。
|
|
11
|
+
- 失败行导出保留规范化错误码和工具名,不输出原始上游响应或凭据。
|
|
12
|
+
- 修复自动展开后关闭/切换会话时,排队中的尺寸回调重新写入布局留白的竞态。
|
|
13
|
+
- 延续 0.8.21 的实际 Host 文件地址和执行自动展开功能。
|
|
14
|
+
|
|
7
15
|
## [0.8.21] - 2026-09-09
|
|
8
16
|
|
|
9
17
|
- 从实际 Host 请求获取文件地址的协议和主机;修复本地 HTTP 链接被补成 HTTPS 的问题。
|
package/README.en.md
CHANGED
|
@@ -8,7 +8,7 @@ Related agents: [数据清洗补全](https://github.com/duhu2000/dsh-data-cleani
|
|
|
8
8
|
|
|
9
9
|
> 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.
|
|
10
10
|
>
|
|
11
|
-
> Current source version / 当前源码版本: **0.8.
|
|
11
|
+
> Current source version / 当前源码版本: **0.8.22** (stable release)
|
|
12
12
|
|
|
13
13
|
This release unifies spreadsheet previews, column mapping, and enrichment scope across the prompt wizard and workbench. Mapping statuses use color and text; mapped fields automatically enter the scope, with optional extra fields collapsed. Multiple confirmed output columns may share a non-identity field while preserving non-empty values. It fixes saved drafts resetting the scope to five defaults and detects stale Host versions. Preparing a draft does not query QCC; sending starts execution. Fully restart DSH after upgrading. Existing download artifacts are not rewritten.
|
|
14
14
|
|
package/README.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# dsh-data-cleaning-agent
|
|
2
2
|
|
|
3
|
-
本版统一向导与工作台的 Host 执行闭环:发送后自动生成新 Excel,原文件不修改,工作台入口可恢复;发布记录见 [发布说明](docs/RELEASE-0.8.
|
|
3
|
+
本版统一向导与工作台的 Host 执行闭环:发送后自动生成新 Excel,原文件不修改,工作台入口可恢复;发布记录见 [发布说明](docs/RELEASE-0.8.22.md)。
|
|
4
4
|
|
|
5
5
|
## 安装与三分钟上手
|
|
6
6
|
|
|
7
7
|
数据清洗补全智能体:面向 Excel/CSV/JSON 企业名单,提供数据清洗、表格清洗、清洗补全、去重、企业数据补全与字段补全,支持企查查 MCP 和结果导出。
|
|
8
8
|
|
|
9
9
|
```sh
|
|
10
|
-
dsh plugin --profile web add dsh-data-cleaning-agent@0.8.
|
|
10
|
+
dsh plugin --profile web add dsh-data-cleaning-agent@0.8.22
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
请先满足下文的 DSH、连接器及侧边栏依赖要求;安装后完整停止并重启对应 Profile。
|
|
@@ -25,7 +25,7 @@ dsh plugin --profile web add dsh-data-cleaning-agent@0.8.21
|
|
|
25
25
|
|
|
26
26
|
> 在 DeepSeek Harness 中清洗、补全、画像企业名单数据的智能体插件:本地 CSV/XLSX/JSON 引擎 + 可选企查查(Qichacha/QCC)MCP 企业数据补全,由企查查(Qichacha/QCC)团队发起并维护。
|
|
27
27
|
>
|
|
28
|
-
> 当前源码版本 / Current source version: **0.8.
|
|
28
|
+
> 当前源码版本 / Current source version: **0.8.22**(正式版本)
|
|
29
29
|
|
|
30
30
|
本版上传表格后展示完整清单及空白数量,用绿色、琥珀色、红色及文字区分已通过、待确认和未匹配映射。已映射字段自动纳入补全范围,额外字段默认折叠;多个原列可经确认使用同一非主体字段,分别补空并保留非空原值。修复 Host 草稿重置为默认五字段的问题,增加前后端版本错配提示。生成说明不查询,发送才执行;升级后需完整重启 DSH,历史下载文件不自动改写。
|
|
31
31
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# 0.8.22 发布说明
|
|
2
|
+
|
|
3
|
+
包含 0.8.21 的实际 Host 协议文件链接与执行自动展开功能;额外修复尺寸回调在工作台关闭后写回留白的竞态。
|
|
4
|
+
|
|
5
|
+
- 表格不压缩列宽,支持左右滚动;纵向滚动固定表头。
|
|
6
|
+
- 预览和下载操作分行留白,长文件名不再挤压按钮。
|
|
7
|
+
- 单独显示失败数量;失败行在异常清单保留规范化错误码和工具名。
|
|
8
|
+
|
|
9
|
+
本次不改变企查查查询范围,不自动重跑历史任务;历史异常文件不会补写已遗漏的错误信息。
|
|
10
|
+
|
|
11
|
+
升级后完整重启 DSH。历史错误链接文本不会重写,可从工作台访问原有文件,不需要重新查询。
|
package/lib/client.js
CHANGED
|
@@ -89,19 +89,27 @@ window.__ModuleLoader__.load({
|
|
|
89
89
|
const handle = drawer.querySelector('.dcAgentResizeHandle');
|
|
90
90
|
if (!handle || !view) return () => {};
|
|
91
91
|
const reservations = new Map();
|
|
92
|
+
const registryKey = Symbol.for('dsh.data-cleaning.sizing-reservations');
|
|
93
|
+
const registry = doc[registryKey] || (doc[registryKey] = new WeakMap());
|
|
94
|
+
let disposed = false;
|
|
92
95
|
let requested = expanded ? 980 : preferredWidth;
|
|
93
96
|
let current = 0;
|
|
94
97
|
let drag = null;
|
|
95
98
|
const boundsForView = () => workbenchWidthBounds(view.innerWidth,
|
|
96
99
|
doc.querySelector('[data-conversation-scroll]')?.getBoundingClientRect().width || view.innerWidth);
|
|
97
100
|
const reserve = () => {
|
|
101
|
+
if (disposed) return;
|
|
98
102
|
const width = boundsForView().mobile ? 0 : drawer.getBoundingClientRect().width;
|
|
99
103
|
for (const el of doc.querySelectorAll('[data-conversation-scroll]')) {
|
|
100
104
|
if (!reservations.has(el)) {
|
|
101
|
-
|
|
105
|
+
const previous = registry.get(el) || {
|
|
102
106
|
value: el.style.getPropertyValue('--dc-agent-workbench-reserve'),
|
|
103
107
|
priority: el.style.getPropertyPriority('--dc-agent-workbench-reserve'),
|
|
104
|
-
|
|
108
|
+
owners: 0,
|
|
109
|
+
};
|
|
110
|
+
previous.owners += 1;
|
|
111
|
+
registry.set(el, previous);
|
|
112
|
+
reservations.set(el, previous);
|
|
105
113
|
sizeObserver?.observe(el, { box: 'border-box' });
|
|
106
114
|
}
|
|
107
115
|
if (el.style.getPropertyValue('--dc-agent-workbench-reserve') !== `${width}px`) {
|
|
@@ -110,6 +118,7 @@ window.__ModuleLoader__.load({
|
|
|
110
118
|
}
|
|
111
119
|
};
|
|
112
120
|
const apply = (value) => {
|
|
121
|
+
if (disposed) return;
|
|
113
122
|
const bounds = boundsForView();
|
|
114
123
|
const fallback = view.innerWidth <= 1040 ? Math.min(420, view.innerWidth * .48) : Math.min(460, view.innerWidth * .42);
|
|
115
124
|
current = Math.round(Math.min(bounds.max, Math.max(bounds.min, Number.isFinite(value) ? value : fallback)));
|
|
@@ -173,6 +182,7 @@ window.__ModuleLoader__.load({
|
|
|
173
182
|
observer?.observe(doc.body, { childList: true, subtree: true });
|
|
174
183
|
apply(requested);
|
|
175
184
|
return () => {
|
|
185
|
+
disposed = true;
|
|
176
186
|
cancel();
|
|
177
187
|
observer?.disconnect();
|
|
178
188
|
sizeObserver?.disconnect();
|
|
@@ -188,6 +198,9 @@ window.__ModuleLoader__.load({
|
|
|
188
198
|
drawer.style.removeProperty('--dc-agent-panel-width');
|
|
189
199
|
delete drawer.dataset.narrow;
|
|
190
200
|
for (const [el, previous] of reservations) {
|
|
201
|
+
previous.owners -= 1;
|
|
202
|
+
if (previous.owners > 0) continue;
|
|
203
|
+
registry.delete(el);
|
|
191
204
|
if (previous.value) el.style.setProperty('--dc-agent-workbench-reserve', previous.value, previous.priority);
|
|
192
205
|
else el.style.removeProperty('--dc-agent-workbench-reserve');
|
|
193
206
|
}
|
|
@@ -970,6 +983,25 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
970
983
|
}
|
|
971
984
|
.dcAgentFieldAction:hover, .dcAgentFieldAction:focus-visible { background: var(--dc-selected); }
|
|
972
985
|
.dcAgentPreviewTable { margin-top: 12px; overflow: auto; border: 1px solid var(--dc-border); border-radius: 8px; }
|
|
986
|
+
.dcAgentArtifactList { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 16px; min-width: 0; }
|
|
987
|
+
.dcAgentArtifactList > .dcAgentButton { display: inline-flex; align-items: center; box-sizing: border-box; max-width: 100%; min-width: 0; height: auto; white-space: normal; overflow-wrap: anywhere; line-height: 1.5; text-decoration: none; }
|
|
988
|
+
.dcAgentArtifactList > a.dcAgentButton { flex-basis: 100%; }
|
|
989
|
+
.dcAgentPreviewTable { min-width: 0; max-width: 100%; scrollbar-gutter: stable; }
|
|
990
|
+
.dcAgentPreviewTable > .dcAgentTable {
|
|
991
|
+
width: max-content; min-width: 100%; max-width: none;
|
|
992
|
+
table-layout: auto; border-collapse: separate; border-spacing: 0;
|
|
993
|
+
}
|
|
994
|
+
.dcAgentPreviewTable > .dcAgentTable th,
|
|
995
|
+
.dcAgentPreviewTable > .dcAgentTable td {
|
|
996
|
+
min-width: 140px; max-width: none; white-space: nowrap;
|
|
997
|
+
word-break: normal; overflow-wrap: normal;
|
|
998
|
+
border-right: 1px solid var(--dc-border);
|
|
999
|
+
}
|
|
1000
|
+
.dcAgentPreviewTable > .dcAgentTable th:first-child,
|
|
1001
|
+
.dcAgentPreviewTable > .dcAgentTable td:first-child { min-width: 64px; }
|
|
1002
|
+
.dcAgentPreviewTable > .dcAgentTable th {
|
|
1003
|
+
position: sticky; top: 0; z-index: 2; background: var(--dc-table-head);
|
|
1004
|
+
}
|
|
973
1005
|
.dcAgentHistoryTask { display: block; width: 100%; padding: 10px; text-align: left; }
|
|
974
1006
|
.dcAgentHistoryTask h3 { margin: 0; font-size: 12px; }
|
|
975
1007
|
/*
|
|
@@ -1863,10 +1895,11 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
1863
1895
|
}
|
|
1864
1896
|
function watchHostedCommand(actions, sessionId, command) {
|
|
1865
1897
|
let openedForExecution = false;
|
|
1898
|
+
const ownerVisible = () => typeof document === 'undefined' || [...document.querySelectorAll('.dcAgentExperience')].some(node => node.dataset.sessionId === sessionId);
|
|
1866
1899
|
void waitForQccCommand(command.commandId, 1800, async (status) => {
|
|
1867
1900
|
if (!status || status.state === 'prepared') return;
|
|
1868
1901
|
await refreshHostedTask(actions, sessionId, command.taskId, null, true).catch(() => {});
|
|
1869
|
-
if (!openedForExecution && isCleaningSession(sessionId) && workflowTaskBySession.get(String(sessionId))?.id === command.taskId) {
|
|
1902
|
+
if (!openedForExecution && ownerVisible() && isCleaningSession(sessionId) && workflowTaskBySession.get(String(sessionId))?.id === command.taskId) {
|
|
1870
1903
|
openedForExecution = true;
|
|
1871
1904
|
openWorkbench(actions, workflowTaskBySession.get(String(sessionId))?.stage || 'match', sessionId);
|
|
1872
1905
|
}
|
|
@@ -2185,6 +2218,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
2185
2218
|
const WORKBENCH_DATASET_EVENT = 'dsh:data-cleaning-workbench-dataset';
|
|
2186
2219
|
const WORKBENCH_DRAFT_EVENT = 'dsh:data-cleaning-workbench-draft';
|
|
2187
2220
|
const WORKBENCH_PREPARE_EVENT = 'dsh:data-cleaning-workbench-prepare';
|
|
2221
|
+
const WORKBENCH_OWNER_LEFT_EVENT = 'dsh:data-cleaning-workbench-owner-left';
|
|
2188
2222
|
|
|
2189
2223
|
// session scope 不能复用 root scope 的 store handle。DSH 当前会分别物化 root/session
|
|
2190
2224
|
// 插槽组件,因此以 document 事件跨 scope 通知;闭包引用仅作为无 DOM 测试降级。
|
|
@@ -2547,6 +2581,10 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
2547
2581
|
function DataCleaningExperience(props) {
|
|
2548
2582
|
const { sessionId, session: ownerSession } = props;
|
|
2549
2583
|
const enabled = useCleaningSession(sessionId);
|
|
2584
|
+
react.useEffect(() => {
|
|
2585
|
+
if (!enabled) return undefined;
|
|
2586
|
+
return () => document.dispatchEvent(new CustomEvent(WORKBENCH_OWNER_LEFT_EVENT, { detail: { sessionId } }));
|
|
2587
|
+
}, [enabled, sessionId]);
|
|
2550
2588
|
const hero = ownerSession?.composerPhase === 'blank';
|
|
2551
2589
|
const [menuMount, setMenuMount] = react.useState(null);
|
|
2552
2590
|
react.useEffect(() => {
|
|
@@ -3428,7 +3466,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
3428
3466
|
h('p', { className: 'dcAgentHint', role: 'status' }, complete
|
|
3429
3467
|
? `共 ${total} 条,当前显示 ${total ? start + 1 : 0}–${Math.min(start + pageSize, total)} 条;共 ${columns.length} 列,可横向滚动。`
|
|
3430
3468
|
: `完整清单尚未就绪:预期 ${expectedCount} 条,当前载入 ${total} 条。请等待同步;刷新后若仍缺失,请重新上传源文件。`),
|
|
3431
|
-
h('div', { className: 'dcAgentPreviewTable', style: { overflow: 'auto', maxHeight: '420px' } },
|
|
3469
|
+
h('div', { className: 'dcAgentPreviewTable', tabIndex: 0, role: 'region', 'aria-label': '表格预览,可横向和纵向滚动,表头固定', style: { overflow: 'auto', maxHeight: '420px' } },
|
|
3432
3470
|
h('table', { className: 'dcAgentTable' },
|
|
3433
3471
|
h('thead', null, h('tr', null, h('th', null, '序号'), columns.map((key) => h('th', { key }, resultFieldLabel(key))))),
|
|
3434
3472
|
h('tbody', null, rows.slice(start, start + pageSize).map((row, index) => h('tr', { key: start + index },
|
|
@@ -3493,6 +3531,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
3493
3531
|
|
|
3494
3532
|
react.useEffect(() => {
|
|
3495
3533
|
rootWorkbenchActions = actions;
|
|
3534
|
+
const handleOwnerLeft = () => actions.close();
|
|
3496
3535
|
const handleOpen = (event) => {
|
|
3497
3536
|
event?.preventDefault?.();
|
|
3498
3537
|
const detail = event?.detail ?? {};
|
|
@@ -3545,6 +3584,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
3545
3584
|
};
|
|
3546
3585
|
if (typeof document !== 'undefined' && typeof document.addEventListener === 'function') {
|
|
3547
3586
|
document.addEventListener(WORKBENCH_OPEN_EVENT, handleOpen);
|
|
3587
|
+
document.addEventListener(WORKBENCH_OWNER_LEFT_EVENT, handleOwnerLeft);
|
|
3548
3588
|
document.addEventListener(WORKBENCH_DATASET_EVENT, handleDataset);
|
|
3549
3589
|
document.addEventListener(WORKBENCH_DRAFT_EVENT, handleDraft);
|
|
3550
3590
|
document.addEventListener(WORKBENCH_PREPARE_EVENT, handlePrepare);
|
|
@@ -3552,6 +3592,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
3552
3592
|
return () => {
|
|
3553
3593
|
if (typeof document !== 'undefined' && typeof document.removeEventListener === 'function') {
|
|
3554
3594
|
document.removeEventListener(WORKBENCH_OPEN_EVENT, handleOpen);
|
|
3595
|
+
document.removeEventListener(WORKBENCH_OWNER_LEFT_EVENT, handleOwnerLeft);
|
|
3555
3596
|
document.removeEventListener(WORKBENCH_DATASET_EVENT, handleDataset);
|
|
3556
3597
|
document.removeEventListener(WORKBENCH_DRAFT_EVENT, handleDraft);
|
|
3557
3598
|
document.removeEventListener(WORKBENCH_PREPARE_EVENT, handlePrepare);
|
|
@@ -4143,6 +4184,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
4143
4184
|
? (qccRun.summary?.ambiguous ?? 0) + (qccRun.summary?.fieldReview ?? 0)
|
|
4144
4185
|
: cachedTask?.enrichmentSummary?.reviewRequired
|
|
4145
4186
|
?? cachedTask?.matchSummary?.reviewRequired;
|
|
4187
|
+
const qccFailedCount = qccRun?.summary?.failed ?? cachedTask?.enrichmentSummary?.failed ?? cachedTask?.matchSummary?.failed ?? 0;
|
|
4146
4188
|
const stat = (label, value, tone) => h('div', { className: 'dcAgentCard' },
|
|
4147
4189
|
h('span', null, label),
|
|
4148
4190
|
h('b', { className: tone ? `is-${tone}` : null }, displayStatValue(value))
|
|
@@ -4378,12 +4420,13 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
4378
4420
|
const availableArtifacts = (cachedTask?.artifacts || []).filter(artifact => artifact.kind !== 'review' || artifact.rowCount > 0);
|
|
4379
4421
|
const canCreateArtifacts = Boolean(exportRows()?.length) && ['rules_confirmed', 'diagnosed', 'export_ready', 'partial'].includes(cachedTask?.state);
|
|
4380
4422
|
pane = h('div', { className: 'dcAgentPane' },
|
|
4381
|
-
h('p', { className: 'dcAgentHint' }, '结果文件由 Host
|
|
4423
|
+
h('p', { className: 'dcAgentHint' }, '结果文件由 Host 保存;有失败、未匹配或待核验记录时展示异常清单。任务或插件重启后,可从任务历史继续下载;无需再次调用企查查。'),
|
|
4382
4424
|
h('div', { className: 'dcAgentGrid' },
|
|
4383
4425
|
stat('输入行数', dataset ? dataset.rowCount : workflowTask?.source?.rowCount ?? '—'),
|
|
4384
4426
|
stat('匹配补全', qccEnrichedCount, qccEnrichedCount > 0 ? 'good' : null),
|
|
4385
4427
|
stat('待核验', qccReviewCount, qccReviewCount > 0 ? 'warn' : null),
|
|
4386
4428
|
stat('任务状态', WORKFLOW_STATE_LABELS[cachedTask?.state] || cachedTask?.state || '进行中'),
|
|
4429
|
+
stat('失败', qccFailedCount, qccFailedCount > 0 ? 'bad' : null),
|
|
4387
4430
|
),
|
|
4388
4431
|
availableArtifacts.length ? h('div', { className: 'dcAgentArtifactList' },
|
|
4389
4432
|
availableArtifacts.filter(artifact => artifact.format === 'xlsx').map(artifact => h('a', {
|
|
@@ -4560,8 +4603,8 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
4560
4603
|
max: commandProgress.totalUnique, value: Math.min(commandProgress.totalUnique, Math.max(0, commandProgress.completedUnique || 0)),
|
|
4561
4604
|
'aria-label': '主体处理进度', style: { width: '100%', accentColor: cachedTask.state === 'completed' ? '#16845b' : cachedTask.state === 'failed' ? '#c62828' : cachedTask.state === 'partial' ? '#a66a00' : '#087dcc' },
|
|
4562
4605
|
}) : null,
|
|
4563
|
-
h('p', { style: { color: Number(qccReviewCount) > 0 ? '#a66a00' :
|
|
4564
|
-
Number.isFinite(qccEnrichedCount) ? `已处理并补全 ${qccEnrichedCount} 条 · 待核验 ${Number.isFinite(qccReviewCount) ? qccReviewCount : '统计中'} 条(按输入行统计;未披露字段保留空白)` : '结果统计中,处理结束后展示补全与待核验数量'),
|
|
4606
|
+
h('p', { style: { color: qccFailedCount > 0 ? '#c62828' : Number(qccReviewCount) > 0 ? '#a66a00' : qccEnrichedCount > 0 ? '#16845b' : 'inherit' } },
|
|
4607
|
+
Number.isFinite(qccEnrichedCount) ? `已处理并补全 ${qccEnrichedCount} 条 · 待核验 ${Number.isFinite(qccReviewCount) ? qccReviewCount : '统计中'} 条 · 失败 ${qccFailedCount} 条(按输入行统计;未披露字段保留空白)` : '结果统计中,处理结束后展示补全与待核验数量'),
|
|
4565
4608
|
) : null,
|
|
4566
4609
|
error ? h('div', { className: 'dcAgentError', role: 'alert' }, error) : null,
|
|
4567
4610
|
step !== 'history' ? h('details', { className: 'dcAgentSection' },
|
package/lib/qcc.js
CHANGED
|
@@ -1074,7 +1074,11 @@ export class QccHostBridge {
|
|
|
1074
1074
|
...(result.fieldIssues ? { qcc_field_notes: Object.entries(result.fieldIssues).filter(([, issue]) => issue.reviewRequired === false).map(([field, issue]) => field + ': ' + issue.message).join(';') } : {}),
|
|
1075
1075
|
};
|
|
1076
1076
|
}
|
|
1077
|
-
return {
|
|
1077
|
+
return {
|
|
1078
|
+
...row, qcc_match_status: result?.status ?? 'failed',
|
|
1079
|
+
// Only export normalized diagnostic identifiers, never raw upstream messages or credentials.
|
|
1080
|
+
...(result?.error ? { qcc_error: [result.error.code, result.error.toolName, result.error.upstreamCode].filter(Boolean).join(' · ') } : {}),
|
|
1081
|
+
};
|
|
1078
1082
|
});
|
|
1079
1083
|
|
|
1080
1084
|
const indexesFor = (name) => normalized.filter((item) => item.companyName === name).map((item) => item.index);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-data-cleaning-agent",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.22",
|
|
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",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"docs/RELEASE-0.8.1.md",
|
|
41
41
|
"docs/RELEASE-0.8.16.md",
|
|
42
42
|
"docs/RELEASE-0.8.17.md",
|
|
43
|
-
"docs/RELEASE-0.8.
|
|
43
|
+
"docs/RELEASE-0.8.22.md",
|
|
44
44
|
"docs/TEMPLATE-MAPPING-ACCEPTANCE.md",
|
|
45
45
|
"docs/UI-WORKFLOW-V2.md",
|
|
46
46
|
"docs/UI-WORKFLOW-V2-MIGRATION.md",
|
package/docs/RELEASE-0.8.21.md
DELETED