dsh-data-cleaning-agent 0.8.2 → 0.8.4
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 +15 -0
- package/README.en.md +1 -1
- package/README.md +1 -1
- package/lib/client.js +101 -44
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,21 @@
|
|
|
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.4] - 2026-09-06
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- 向导数据来源页在文本模式也接管图片粘贴,避免 Modlens 图片路径被当成企业名称;文本名单明确拒绝本地图片路径。
|
|
9
|
+
- 右侧上传允许 PNG/JPEG/WebP,并通过同会话事件桥转交图片向导;接收失败保留工作台并说明原因。
|
|
10
|
+
- 回填前检查原生输入机提交状态,回填后核对草稿;输入机未接收时保留向导并提示,不强制启用发送按钮。
|
|
11
|
+
- 移除通过全局捕获点击和按钮文案推测导航的逻辑,改为订阅真实会话选择,目标打开失败时保留清洗首页、工作台和草稿。
|
|
12
|
+
- 兼容无回调参数的 Store 通知;成功退出时只清理插件默认文案,保留用户自写草稿。
|
|
13
|
+
- 新清洗会话在准备和选择成功后才激活,避免提前撤销旧会话归属。
|
|
14
|
+
|
|
15
|
+
## [0.8.3] - 2026-09-06
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
- 「新会话」不再复用数据清洗入口的空白会话:入口从 `sessions.create({ workspaceId, sessionId })` 改为 `sessions.create({ cwd, sessionId })`,仅以工作区路径创建、不再挂进工作区 `sessionIds`,DSH「新会话」的空白会话复用因此跳过它,恢复默认 DSH 标准页;只有点击「数据清洗补全」才进入带标题的工作台初始页。
|
|
19
|
+
|
|
5
20
|
## [0.8.2] - 2026-09-06
|
|
6
21
|
|
|
7
22
|
### Fixed
|
package/README.en.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
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.
|
|
5
|
+
> Current source version / 当前源码版本: **0.8.4** (stable release)
|
|
6
6
|
|
|
7
7
|
[](https://github.com/duhu2000/dsh-data-cleaning-agent/actions/workflows/ci.yml)
|
|
8
8
|
[](https://www.npmjs.com/package/dsh-data-cleaning-agent)
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> 在 DeepSeek Harness 中清洗、补全、画像企业名单数据的智能体插件:本地 CSV/XLSX/JSON 引擎 + 可选企查查(Qichacha/QCC)MCP 企业数据补全,由企查查(Qichacha/QCC)团队发起并维护。
|
|
4
4
|
>
|
|
5
|
-
> 当前源码版本 / Current source version: **0.8.
|
|
5
|
+
> 当前源码版本 / Current source version: **0.8.4**(正式版本)
|
|
6
6
|
|
|
7
7
|
[](https://github.com/duhu2000/dsh-data-cleaning-agent/actions/workflows/ci.yml)
|
|
8
8
|
[](https://www.npmjs.com/package/dsh-data-cleaning-agent)
|
package/lib/client.js
CHANGED
|
@@ -1105,9 +1105,8 @@ window.__ModuleLoader__.load({
|
|
|
1105
1105
|
}
|
|
1106
1106
|
|
|
1107
1107
|
/**
|
|
1108
|
-
*
|
|
1109
|
-
*
|
|
1110
|
-
* 提示词、能力栏或工作台。点击本插件自己的顶部入口不会提前撤销。
|
|
1108
|
+
* 以实际会话选择提交作为退出条件;点击其它入口但创建失败时,保留清洗首页、
|
|
1109
|
+
* 面板和用户草稿。新版本入口始终创建独立会话,不再依赖 DOM 文案推测导航。
|
|
1111
1110
|
*/
|
|
1112
1111
|
function installSessionOwnershipBridge(ctx) {
|
|
1113
1112
|
let staleDraftObserver = null;
|
|
@@ -1124,26 +1123,9 @@ window.__ModuleLoader__.load({
|
|
|
1124
1123
|
};
|
|
1125
1124
|
const leaveSubsystem = () => {
|
|
1126
1125
|
const sessionId = activeCleaningSessionId;
|
|
1127
|
-
if (sessionId) clearCleaningDraft(ctx, sessionId);
|
|
1126
|
+
if (sessionId) clearCleaningDraft(ctx, sessionId, true);
|
|
1128
1127
|
deactivateCleaningSession(sessionId);
|
|
1129
1128
|
};
|
|
1130
|
-
const handleSidebarNavigation = (event) => {
|
|
1131
|
-
if (!activeCleaningSessionId) return;
|
|
1132
|
-
const target = event?.target;
|
|
1133
|
-
if (!target || typeof target.closest !== 'function') return;
|
|
1134
|
-
if (target.closest('.dcAgentLauncher, .dcAgentExperience, .dcAgentPromptPopover, .dcAgentWorkbench, .dcAgentHeaderAction')) return;
|
|
1135
|
-
|
|
1136
|
-
const actionable = target.closest('button, a, [role="button"]');
|
|
1137
|
-
if (!actionable) return;
|
|
1138
|
-
const workspaceSlot = document.querySelector?.(SIDEBAR_WORKSPACES_SELECTOR);
|
|
1139
|
-
const sidebarRoot = workspaceSlot?.closest?.('aside, nav, [data-slot="sidebar"], [class*="sidebar"]')
|
|
1140
|
-
?? workspaceSlot?.parentElement;
|
|
1141
|
-
const label = `${actionable.getAttribute?.('aria-label') ?? ''} ${actionable.textContent ?? ''}`.trim();
|
|
1142
|
-
const sessionOrAgentEntry = /新建?会话|新会话|new\s+session|智能体|agent|尽调/i.test(label);
|
|
1143
|
-
if (sidebarRoot?.contains?.(actionable) || sessionOrAgentEntry) leaveSubsystem();
|
|
1144
|
-
};
|
|
1145
|
-
|
|
1146
|
-
document.addEventListener?.('click', handleSidebarNavigation, true);
|
|
1147
1129
|
// 升级 / 刷新后不恢复子系统所有权;仅清理由旧版本遗留且仍未被用户编辑的默认文案。
|
|
1148
1130
|
clearStaleDefaultDraft();
|
|
1149
1131
|
// DSH 会在插件 apply() 之后异步恢复 composer draft。在首屏稳定期内
|
|
@@ -1163,15 +1145,17 @@ window.__ModuleLoader__.load({
|
|
|
1163
1145
|
}, 10_000);
|
|
1164
1146
|
}
|
|
1165
1147
|
const unsubscribe = ctx.sessions?.list?.subscribe?.((snapshot) => {
|
|
1166
|
-
|
|
1167
|
-
|
|
1148
|
+
// Store subscriptions may signal without a payload; read authoritative state.
|
|
1149
|
+
const selected = ctx.sessions?.list?.getSnapshot?.() ?? snapshot;
|
|
1150
|
+
if (!selected) return;
|
|
1151
|
+
const nextSessionId = selected.current;
|
|
1152
|
+
if (activeCleaningSessionId && nextSessionId !== activeCleaningSessionId) {
|
|
1168
1153
|
leaveSubsystem();
|
|
1169
1154
|
} else if (!activeCleaningSessionId) {
|
|
1170
1155
|
clearStaleDefaultDraft();
|
|
1171
1156
|
}
|
|
1172
1157
|
});
|
|
1173
1158
|
return () => {
|
|
1174
|
-
document.removeEventListener?.('click', handleSidebarNavigation, true);
|
|
1175
1159
|
staleDraftObserver?.disconnect();
|
|
1176
1160
|
if (staleDraftObserverTimer !== null) clearTimeout(staleDraftObserverTimer);
|
|
1177
1161
|
if (typeof unsubscribe === 'function') unsubscribe();
|
|
@@ -1579,29 +1563,32 @@ window.__ModuleLoader__.load({
|
|
|
1579
1563
|
const workspace = ctx.workspaces.list.getSnapshot();
|
|
1580
1564
|
const current = ctx.sessions.list.getSnapshot().current;
|
|
1581
1565
|
const items = Array.isArray(workspace.items) ? workspace.items : [];
|
|
1582
|
-
const
|
|
1566
|
+
const currentWorkspace = current === undefined
|
|
1583
1567
|
? undefined
|
|
1584
|
-
: items.find((item) => Array.isArray(item.sessionIds) && item.sessionIds.includes(current))
|
|
1585
|
-
const
|
|
1586
|
-
|
|
1568
|
+
: items.find((item) => Array.isArray(item.sessionIds) && item.sessionIds.includes(current));
|
|
1569
|
+
const recentWorkspace = items.find((item) => item.workspaceId === workspace.recentWorkspaceId);
|
|
1570
|
+
const cwd = currentWorkspace?.path ?? recentWorkspace?.path ?? items[0]?.path;
|
|
1571
|
+
if (cwd === undefined) {
|
|
1587
1572
|
throw new Error('请先选择一个工作空间,再打开数据清洗补全智能体');
|
|
1588
1573
|
}
|
|
1589
1574
|
// 单一会话所有权:与招投标入口一致,显式创建带前缀的独立原生会话,绝不复用空白会话。
|
|
1590
1575
|
// connectWorkspace 会把「招投标」尚为空白的工作台会话复用为清洗会话,
|
|
1591
1576
|
// 使同一会话同时被招投标与清洗两个插件认领,进而争夺 Hero 标题与右侧工作台面板。
|
|
1577
|
+
// 只用 cwd 创建(不传 workspaceId):会话不挂进工作区,
|
|
1578
|
+
// 「新会话」的 blank 复用逻辑就不会把它当成空白会话复用。
|
|
1592
1579
|
if (typeof ctx.sessions.create !== 'function') {
|
|
1593
1580
|
throw new Error('当前 DSH 版本没有可用的独立会话创建能力');
|
|
1594
1581
|
}
|
|
1595
1582
|
const requestedId = createCleaningSessionId();
|
|
1596
|
-
const sessionId = await ctx.sessions.create({
|
|
1583
|
+
const sessionId = await ctx.sessions.create({ cwd, sessionId: requestedId });
|
|
1597
1584
|
if (sessionId !== requestedId) {
|
|
1598
1585
|
throw new Error('当前 DSH 版本不支持独立会话创建,请升级 DSH 后再打开数据清洗补全智能体');
|
|
1599
1586
|
}
|
|
1600
1587
|
const conversation = typeof ctx.get === 'function' ? ctx.get('conversation') : ctx.conversation;
|
|
1601
1588
|
if (!conversation) throw new Error('DSH 对话服务尚未就绪,请稍后重试');
|
|
1602
|
-
markCleaningSession(sessionId);
|
|
1603
1589
|
conversation.input.shell(sessionId).setDraft(DEFAULT_SESSION_PROMPT);
|
|
1604
1590
|
ctx.sessions.open(sessionId);
|
|
1591
|
+
markCleaningSession(sessionId);
|
|
1605
1592
|
return sessionId;
|
|
1606
1593
|
}
|
|
1607
1594
|
|
|
@@ -1990,6 +1977,18 @@ window.__ModuleLoader__.load({
|
|
|
1990
1977
|
.filter(Boolean);
|
|
1991
1978
|
}
|
|
1992
1979
|
|
|
1980
|
+
function isImagePathEntry(value) {
|
|
1981
|
+
return /^(?:file:\/\/|\/|[a-z]:[\\/])/i.test(String(value).trim().replace(/^["']/, ''))
|
|
1982
|
+
&& /\.(?:png|jpe?g|webp|gif|heic|bmp)(?:["']|\s)*$/i.test(String(value));
|
|
1983
|
+
}
|
|
1984
|
+
|
|
1985
|
+
function requestPromptImage(sessionId, file = null) {
|
|
1986
|
+
if (!sessionId || typeof document.createEvent !== 'function') return false;
|
|
1987
|
+
const event = document.createEvent('CustomEvent');
|
|
1988
|
+
event.initCustomEvent('dsh:data-cleaning-prompt-image', false, true, { sessionId, file });
|
|
1989
|
+
return !document.dispatchEvent(event);
|
|
1990
|
+
}
|
|
1991
|
+
|
|
1993
1992
|
async function imageFileBase64(file) {
|
|
1994
1993
|
if (!file || typeof file.arrayBuffer !== 'function') throw new Error('图片文件不可读。');
|
|
1995
1994
|
const bytes = new Uint8Array(await file.arrayBuffer());
|
|
@@ -2013,7 +2012,7 @@ window.__ModuleLoader__.load({
|
|
|
2013
2012
|
}
|
|
2014
2013
|
|
|
2015
2014
|
function PromptGenerator(props) {
|
|
2016
|
-
const { sessionId, inputActions, attachImages, removeImage } = props;
|
|
2015
|
+
const { sessionId, inputActions, attachImages, removeImage, getInputSnapshot } = props;
|
|
2017
2016
|
const enabled = useCleaningSession(sessionId);
|
|
2018
2017
|
const [open, setOpen] = react.useState(false);
|
|
2019
2018
|
const [wizardStep, setWizardStep] = react.useState(1);
|
|
@@ -2174,6 +2173,7 @@ window.__ModuleLoader__.load({
|
|
|
2174
2173
|
const validateSource = () => {
|
|
2175
2174
|
const values = selectedEntries();
|
|
2176
2175
|
if (mode === 'text' && !values.length) return '请先录入企业名称或统一社会信用代码,每行一条。';
|
|
2176
|
+
if (mode === 'text' && values.some(isImagePathEntry)) return '检测到图片文件路径,不是企业名单。请切换「上传图片识别」,重新选择或粘贴图片。';
|
|
2177
2177
|
if (mode === 'excel' && !values.length) return '请先上传并解析 Excel / CSV / JSON 文件。';
|
|
2178
2178
|
if (mode === 'image' && !imageCommand) return '请先选择、粘贴或拖入一张包含企业名单的图片。';
|
|
2179
2179
|
if (mode === 'image' && imageCommand?.state === 'failed') return imageCommand.error?.message || '图片识别失败,请重新选择图片。';
|
|
@@ -2202,13 +2202,26 @@ window.__ModuleLoader__.load({
|
|
|
2202
2202
|
setError('当前会话输入机尚未就绪,请稍后重试。');
|
|
2203
2203
|
return;
|
|
2204
2204
|
}
|
|
2205
|
+
const inputSnapshot = getInputSnapshot?.(sessionId);
|
|
2206
|
+
if (['adjudicating', 'submitting'].includes(inputSnapshot?.phase)) {
|
|
2207
|
+
setError('当前对话正在提交,请等待完成后再回填。图片与字段选择已保留。');
|
|
2208
|
+
return;
|
|
2209
|
+
}
|
|
2205
2210
|
const config = promptConfig();
|
|
2206
2211
|
if (mode === 'image' && imageCommand?.state === 'prepared' && imageAttachment && typeof removeImage === 'function') {
|
|
2207
2212
|
// qcc-document-mcp 只读取 Host 暂存文件;发送前释放原生附件,文本模型不会收到图片。
|
|
2208
2213
|
removeImage(sessionId, imageAttachment);
|
|
2209
2214
|
setImageAttachment(null);
|
|
2210
2215
|
}
|
|
2211
|
-
|
|
2216
|
+
const prompt = buildTaskPrompt(config);
|
|
2217
|
+
try {
|
|
2218
|
+
inputActions.setDraft(prompt);
|
|
2219
|
+
const updatedInput = getInputSnapshot?.(sessionId);
|
|
2220
|
+
if (updatedInput && updatedInput.draft !== prompt) throw new Error('当前对话尚未接收任务说明,请稍后重试回填。');
|
|
2221
|
+
} catch (draftError) {
|
|
2222
|
+
setError(draftError instanceof Error ? draftError.message : String(draftError));
|
|
2223
|
+
return;
|
|
2224
|
+
}
|
|
2212
2225
|
if (mode === 'text') {
|
|
2213
2226
|
requestWorkbenchDataset(entriesToDataset(config.entries), sessionId, { type: 'text', fileName: '' });
|
|
2214
2227
|
}
|
|
@@ -2257,22 +2270,38 @@ window.__ModuleLoader__.load({
|
|
|
2257
2270
|
const hasImage = files.length > 0;
|
|
2258
2271
|
if (!hasImage) return;
|
|
2259
2272
|
const target = event.target;
|
|
2260
|
-
const inComposer = !open &&
|
|
2261
|
-
|
|
2262
|
-
|
|
2273
|
+
const inComposer = !open && !target?.closest?.('.dcAgentWorkbench')
|
|
2274
|
+
&& Boolean(target?.closest?.('textarea, [contenteditable="true"], [role="textbox"]'));
|
|
2275
|
+
const inSourceStep = open && wizardStep === 1 && Boolean(target?.closest?.('.dcAgentPromptPanel'));
|
|
2276
|
+
if (!inComposer && !inSourceStep) return;
|
|
2263
2277
|
event.preventDefault();
|
|
2264
2278
|
event.stopImmediatePropagation?.();
|
|
2265
|
-
if (
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
}
|
|
2279
|
+
if (busy || imageCommand?.state === 'running') return;
|
|
2280
|
+
setMode('image');
|
|
2281
|
+
setWizardStep(1);
|
|
2282
|
+
setOpen(true);
|
|
2283
|
+
setError(null);
|
|
2271
2284
|
acceptImageFiles(files);
|
|
2272
2285
|
};
|
|
2273
2286
|
window.addEventListener?.('paste', handleWindowPaste, true);
|
|
2274
2287
|
return () => window.removeEventListener?.('paste', handleWindowPaste, true);
|
|
2275
|
-
}, [enabled, open, wizardStep, mode, busy, sessionId]);
|
|
2288
|
+
}, [enabled, open, wizardStep, mode, busy, sessionId, imageCommand, imageAttachment]);
|
|
2289
|
+
|
|
2290
|
+
// 右侧工作台共用此图片入口;仅由当前会话确认接收,不把图片交给表格解析器。
|
|
2291
|
+
react.useEffect(() => {
|
|
2292
|
+
if (!enabled) return undefined;
|
|
2293
|
+
const receiveImage = (event) => {
|
|
2294
|
+
if (event.detail?.sessionId !== sessionId || busy || imageCommand?.state === 'running') return;
|
|
2295
|
+
event.preventDefault();
|
|
2296
|
+
setMode('image');
|
|
2297
|
+
setWizardStep(1);
|
|
2298
|
+
setOpen(true);
|
|
2299
|
+
setError(null);
|
|
2300
|
+
if (event.detail.file) acceptImageFiles([event.detail.file]);
|
|
2301
|
+
};
|
|
2302
|
+
document.addEventListener('dsh:data-cleaning-prompt-image', receiveImage);
|
|
2303
|
+
return () => document.removeEventListener('dsh:data-cleaning-prompt-image', receiveImage);
|
|
2304
|
+
}, [enabled, sessionId, busy, imageCommand, imageAttachment]);
|
|
2276
2305
|
|
|
2277
2306
|
if (!enabled) return null;
|
|
2278
2307
|
|
|
@@ -2855,9 +2884,22 @@ window.__ModuleLoader__.load({
|
|
|
2855
2884
|
}
|
|
2856
2885
|
};
|
|
2857
2886
|
|
|
2887
|
+
const openImageIntake = (file = null) => {
|
|
2888
|
+
if (!requestPromptImage(activeSessionId, file)) {
|
|
2889
|
+
actions.setError('图片入口尚未就绪或正在处理图片,请回到当前清洗会话稍后重试。');
|
|
2890
|
+
return false;
|
|
2891
|
+
}
|
|
2892
|
+
actions.close();
|
|
2893
|
+
return true;
|
|
2894
|
+
};
|
|
2858
2895
|
const handleFile = async (event) => {
|
|
2859
2896
|
const file = event.target && event.target.files && event.target.files[0];
|
|
2860
2897
|
if (!file) return;
|
|
2898
|
+
if (String(file.type ?? '').startsWith('image/')) {
|
|
2899
|
+
openImageIntake(file);
|
|
2900
|
+
event.target.value = '';
|
|
2901
|
+
return;
|
|
2902
|
+
}
|
|
2861
2903
|
actions.setBusy(true);
|
|
2862
2904
|
actions.setError(null);
|
|
2863
2905
|
try {
|
|
@@ -3603,19 +3645,28 @@ window.__ModuleLoader__.load({
|
|
|
3603
3645
|
);
|
|
3604
3646
|
} else {
|
|
3605
3647
|
pane = h('div', { className: 'dcAgentPane' },
|
|
3606
|
-
h('p', { className: 'dcAgentHint' }, '上传 CSV / XLSX / XLS / JSON
|
|
3648
|
+
h('p', { className: 'dcAgentHint' }, '上传 CSV / XLSX / XLS / JSON,或粘贴数据。也可选择图片,通过企查查智能文档解析提取名单后继续清洗补全。'),
|
|
3607
3649
|
h('input', {
|
|
3608
3650
|
type: 'file',
|
|
3609
|
-
accept: '.csv,.json,.xlsx,.xls',
|
|
3651
|
+
accept: '.csv,.json,.xlsx,.xls,image/png,image/jpeg,image/webp',
|
|
3610
3652
|
className: 'dcAgentField',
|
|
3611
3653
|
'aria-label': '选择数据文件',
|
|
3612
3654
|
onChange: handleFile,
|
|
3613
3655
|
}),
|
|
3656
|
+
h('button', { type: 'button', className: 'dcAgentButton', disabled: busy,
|
|
3657
|
+
onClick: () => openImageIntake() }, '图片识别(粘贴 / 选择)'),
|
|
3614
3658
|
h('textarea', {
|
|
3615
3659
|
className: 'dcAgentTextarea',
|
|
3616
3660
|
placeholder: '粘贴 CSV 文本,或 JSON 数组(例如 [{"name":"某公司","amount":"100"}])…',
|
|
3617
3661
|
'aria-label': '粘贴数据',
|
|
3618
3662
|
value: input,
|
|
3663
|
+
onPaste: (event) => {
|
|
3664
|
+
const files = imageFilesFromTransfer(event.clipboardData);
|
|
3665
|
+
if (files.length && openImageIntake(files[0])) {
|
|
3666
|
+
event.preventDefault();
|
|
3667
|
+
event.stopPropagation?.();
|
|
3668
|
+
}
|
|
3669
|
+
},
|
|
3619
3670
|
onInput: (event) => actions.setInput(event.target.value),
|
|
3620
3671
|
}),
|
|
3621
3672
|
dataset ? h('div', { className: 'dcAgentChips' },
|
|
@@ -3767,6 +3818,10 @@ window.__ModuleLoader__.load({
|
|
|
3767
3818
|
inject: () => ({
|
|
3768
3819
|
attachImages: (sessionId, files) => attachPromptImages(ctx, sessionId, files),
|
|
3769
3820
|
removeImage: (sessionId, attachment) => removePromptImage(ctx, sessionId, attachment),
|
|
3821
|
+
getInputSnapshot: (sessionId) => {
|
|
3822
|
+
const conversation = typeof ctx.get === 'function' ? ctx.get('conversation') : ctx.conversation;
|
|
3823
|
+
return conversation?.input?.shell?.(sessionId)?.snapshot;
|
|
3824
|
+
},
|
|
3770
3825
|
}),
|
|
3771
3826
|
}, PromptGenerator));
|
|
3772
3827
|
|
|
@@ -3805,6 +3860,8 @@ window.__ModuleLoader__.load({
|
|
|
3805
3860
|
entriesToDataset,
|
|
3806
3861
|
extractPromptEntries,
|
|
3807
3862
|
imageFilesFromTransfer,
|
|
3863
|
+
isImagePathEntry,
|
|
3864
|
+
requestPromptImage,
|
|
3808
3865
|
guessMappings,
|
|
3809
3866
|
deactivateCleaningSession,
|
|
3810
3867
|
installSessionOwnershipBridge,
|
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.4",
|
|
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",
|