dsh-data-cleaning-agent 0.9.0 → 0.9.1
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 +7 -0
- package/README.en.md +7 -4
- package/README.md +8 -5
- package/docs/COMPATIBILITY.md +20 -2
- package/install.sh +10 -2
- package/lib/client.js +20 -10
- package/lib/install-preflight.js +49 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.9.1] - 2026-09-10
|
|
8
|
+
|
|
9
|
+
- 新宿主 uiWorkspace 生命周期适配:新会话不再复用清洗空会话,普通草稿与菜单隔离。
|
|
10
|
+
- 修复纯本地清洗完成后结果下载被外部补全状态门禁阻断。
|
|
11
|
+
- 安装前只读组合预检,精确阻断已知双向不兼容;安装脚本须从完整包运行。
|
|
12
|
+
- 260 项检查通过;新组合真实隔离 XLSX 导入、映射、清洗、导出、预览与普通会话验证通过。真实 MCP/OCR 和四产品共存尚未验证。
|
|
13
|
+
|
|
7
14
|
## [0.9.0] - 2026-09-10
|
|
8
15
|
|
|
9
16
|
- 工作台迁移到 Better Sidebar Session 单例 Tab;移除自有固定抽屉、宽度拖拽、展开/关闭按钮和中央会话让位逻辑。
|
package/README.en.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# dsh-data-cleaning-agent
|
|
2
2
|
|
|
3
|
-
> 0.9.
|
|
3
|
+
> 0.9.1 upgrade: the workbench now uses a Session-singleton Better Sidebar Tab, requiring `targetedOpen` and `stateSubscription`. Missing providers show an install/upgrade message, not a private drawer. See the [adoption and validation record](docs/UI-V1.5.0-ADOPTION.md).
|
|
4
4
|
|
|
5
5
|
Data cleaning and data enrichment for CSV/XLSX/JSON enterprise lists in DeepSeek Harness, including spreadsheet cleaning, deduplication, profiling, optional Qichacha MCP and exports.
|
|
6
6
|
|
|
@@ -10,7 +10,7 @@ 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.1** (stable release)
|
|
14
14
|
|
|
15
15
|
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.
|
|
16
16
|
|
|
@@ -72,10 +72,13 @@ temporary files. The local server uploads the explicitly submitted file to the Q
|
|
|
72
72
|
Both use the current customer's own QCC account and quota. Without the local connector,
|
|
73
73
|
image intake fails closed with actionable guidance; text and spreadsheet paths remain available.
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
Check the complete DSH `0.1.2-rc.1` + Better Sidebar `0.18.1` combination first. Context is optional; an existing `0.36.0` installation must be upgraded to `0.48.0`. Preflight does not upgrade the global host or prove business acceptance.
|
|
76
|
+
|
|
77
|
+
Run from a full checkout or unpacked npm package with the actual `dsh` CLI (streamed shell installation is no longer supported):
|
|
76
78
|
|
|
77
79
|
```bash
|
|
78
|
-
|
|
80
|
+
node lib/install-preflight.js "$DSH_HOME/profiles/web"
|
|
81
|
+
bash install.sh
|
|
79
82
|
```
|
|
80
83
|
|
|
81
84
|
Or let an agent install it for you:
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# dsh-data-cleaning-agent
|
|
2
2
|
|
|
3
|
-
> 0.9.
|
|
3
|
+
> 0.9.1 升级说明:工作台已迁移到 Better Sidebar 的 Session 单例 Tab,需要兼容的 `dsh-better-sidebar`(`targetedOpen`、`stateSubscription`)。缺失时会提示安装/升级,不回退到自有抽屉;本轮验证边界见 [采用记录](docs/UI-V1.5.0-ADOPTION.md)。
|
|
4
4
|
|
|
5
5
|
本版统一向导与工作台的 Host 执行闭环:发送后自动生成新 Excel,原文件不修改,工作台入口可恢复;发布记录见 [发布说明](docs/RELEASE-0.8.22.md)。
|
|
6
6
|
|
|
@@ -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.1
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
请先满足下文的 DSH、连接器及侧边栏依赖要求;安装后完整停止并重启对应 Profile。
|
|
@@ -27,7 +27,7 @@ dsh plugin --profile web add dsh-data-cleaning-agent@0.9.0
|
|
|
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.1**(正式版本)
|
|
31
31
|
|
|
32
32
|
本版上传表格后展示完整清单及空白数量,用绿色、琥珀色、红色及文字区分已通过、待确认和未匹配映射。已映射字段自动纳入补全范围,额外字段默认折叠;多个原列可经确认使用同一非主体字段,分别补空并保留非空原值。修复 Host 草稿重置为默认五字段的问题,增加前后端版本错配提示。生成说明不查询,发送才执行;升级后需完整重启 DSH,历史下载文件不自动改写。
|
|
33
33
|
|
|
@@ -81,10 +81,13 @@ Composer 图片附件,因此不支持视觉输入的文本模型也能调度 A
|
|
|
81
81
|
或分发凭据。本地服务会把用户明确提交的图片上传到企查查文档解析网关;未连接本地服务时功能会
|
|
82
82
|
fail closed,并明确提示配置要求,文本与 Excel 流程不受影响。
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
安装前请核验完整 DSH `0.1.2-rc.1` + Better Sidebar `0.18.1`。context 不是必装依赖;若已装 `0.36.0`,需先升级到 `0.48.0`。预检不会升级全局宿主,也不代表业务验收通过。
|
|
85
|
+
|
|
86
|
+
从完整源码或解压的 npm 包运行安装脚本(需要实际 `dsh` CLI;不再支持流式脚本):
|
|
85
87
|
|
|
86
88
|
```bash
|
|
87
|
-
|
|
89
|
+
node lib/install-preflight.js "$DSH_HOME/profiles/web"
|
|
90
|
+
bash install.sh
|
|
88
91
|
```
|
|
89
92
|
|
|
90
93
|
或直接让 Agent 安装:
|
package/docs/COMPATIBILITY.md
CHANGED
|
@@ -4,9 +4,27 @@
|
|
|
4
4
|
|
|
5
5
|
工作台通过可选 `ctx.inject(['betterSidebar'], ...)` 接入 Provider,探测 `targetedOpen` 与 `stateSubscription`;缺失时保留会话和 Host 工具,不提供私有抽屉回退。当前仅完成隔离模拟服务与 Chromium 回归,尚未实装组合验收;旧版本的 Host/UI 验证不自动覆盖此次迁移。详见 [采用记录](UI-V1.5.0-ADOPTION.md)。
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## 当前加固目标(2026-09-10)
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
完整 DSH `0.1.2-rc.1` + Better Sidebar `0.18.1`;可选 context 共存版本 `0.48.0`。版本预检通过仅代表排除已知版本冲突,不代表模块加载、服务激活或业务闭环已通过。其他版本提示未验证,旧宿主配 Sidebar 0.18.1、rc.1 配 Sidebar 0.17.1 或 context 0.36.0 阻断安装。反向冲突证据由 AI 填表隔离验收共享:`/tmp/ff-compat-oldhost.log`(实际宿主为 rc.1,文件名并非版本依据),缺少 `settingsNamespace` 导致导入失败。不推断整个版本区间。
|
|
10
|
+
|
|
11
|
+
安装前从完整包运行 `node lib/install-preflight.js <目标Profile目录> [实际dsh可执行文件]`;只读取包版本并执行 CLI `--version`,不读取密钥或修改安装。先备份 Profile 与锁文件,由宿主管理者升级完整宿主,不能只升级 Session 子包;回滚须还原成套宿主和插件锁定版本,不能把 Sidebar 0.18.1 留在旧宿主上。
|
|
12
|
+
|
|
13
|
+
## 1. 历史基线(不代表 0.9.0 新组合承诺)
|
|
14
|
+
|
|
15
|
+
### 本轮隔离证据(2026-09-10,候选未发布)
|
|
16
|
+
|
|
17
|
+
- Node `v25.9.0`;临时根 `/private/tmp/dcq-host-rc1`,独立 DSH_HOME `home`,端口 `43278`。未访问正式 Profile,未调用真实 MCP。
|
|
18
|
+
- npm pack 候选安装到临时 Profile,完整 DSH `0.1.2-rc.1` / Sidebar `0.18.1` / context `0.48.0`:Host apply、真实浏览器入口和 Session Tab 可见,pageErrors 为 0。未用旧 runtime 模块替身。
|
|
19
|
+
- 合成 XLSX(2 行)实际上传、自动映射、规则确认、质量体检、本地确定性清洗、本地补全、生成 XLSX 均执行;导出工作表 `清洗补全结果` 可反向解析,预览 HTTP 200。
|
|
20
|
+
- 实证修复:纯本地任务完成后仍被下载导航的外部补全状态门禁阻断。现在只在非 QCC 目标、规则已确认且确有本地结果时允许进入下载;QCC 目标仍保持原门禁。
|
|
21
|
+
- 第二处实证修复:rc.1 原生 New Session 已迁至 `uiWorkspace.startSession`,旧桥挂在 `workspaces.startSession` 因而失效。现在通过可选服务注入跟随 `uiWorkspace` 生命周期挂载/恢复兼容桥,保留旧接口回退。重打包安装后 New Session 切换、清洗 dock 隐藏、普通会话自写草稿均通过,pageErrors=0。
|
|
22
|
+
- **待验收**:真实 QCC、图片 OCR、候选确认、多插件完整共存和关闭/恢复回归尚未在此组合完成;不能以本地合成闭环代替这些验收。
|
|
23
|
+
- 环境调整:初次跳过 peer 安装缺失宿主依赖,补全后启动;文件监听 EMFILE,测试 Profile 设 `patchReload: startup` 并关闭 settings/credentials watch。磁盘 ENOSPC 曾阻断工作区创建,清理本轮下载缓存后重试成功。上述不是产品兼容通过依据。
|
|
24
|
+
- 重现脚本:`DCQ_PLAYWRIGHT=<playwright模块路径> DCQ_SMOKE_ROOT=/private/tmp/dcq-host-rc1 node scripts/host-rc1-smoke.cjs`。仅对该布局、指定独立端口运行;需先按上文安装包、注册 bundle 并启动测试 Host,脚本不启动或升级宿主。脚本包含普通会话隔离断言,修复后通过。
|
|
25
|
+
- 本机证据:`/private/tmp/dcq-host-rc1/business-result.log`、`startup.png`、`workbench.png`,全量单测/发布包检查 `/private/tmp/dcq-compat-check.log`(260 通过)。本轮 tarball 是未发布候选,沿用基线版本用于隔离安装,**不允许覆盖发布 npm 0.9.0**。
|
|
26
|
+
|
|
27
|
+
以下是旧发布的历史证据,不继承为当前组合验收:
|
|
10
28
|
|
|
11
29
|
| 基线 | 框架 npm 包线 | 备注 |
|
|
12
30
|
| --- | --- | --- |
|
package/install.sh
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
# dsh-data-cleaning-agent 一键安装脚本(DeepSeek Harness)
|
|
3
3
|
# 用法:
|
|
4
4
|
# 本地: bash install.sh
|
|
5
|
-
#
|
|
6
|
-
#
|
|
5
|
+
# 请从完整 npm 包或源码目录运行,确保随包预检可用。
|
|
6
|
+
# 需要实际 dsh CLI 通过预检;脚本不会升级全局宿主。
|
|
7
7
|
# 幂等:重复执行不会重复注册或破坏已有配置。
|
|
8
8
|
set -euo pipefail
|
|
9
9
|
|
|
@@ -21,6 +21,14 @@ if [ ! -d "$PROFILE_DIR" ]; then
|
|
|
21
21
|
exit 1
|
|
22
22
|
fi
|
|
23
23
|
|
|
24
|
+
# 在任何安装/配置写入前,只读检查实际 CLI 与目标 Profile 的组合。
|
|
25
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
26
|
+
if [ ! -f "$SCRIPT_DIR/lib/install-preflight.js" ]; then
|
|
27
|
+
echo "错误:缺少随包预检。请解压 npm pack dsh-data-cleaning-agent 的完整包后运行 bash package/install.sh;不再支持流式执行脚本。"
|
|
28
|
+
exit 1
|
|
29
|
+
fi
|
|
30
|
+
node "$SCRIPT_DIR/lib/install-preflight.js" "$PROFILE_DIR"
|
|
31
|
+
|
|
24
32
|
# ── 1) 安装依赖 ──
|
|
25
33
|
if command -v dsh >/dev/null 2>&1; then
|
|
26
34
|
echo "==> dsh plugin --profile $PROFILE add $PKG"
|
package/lib/client.js
CHANGED
|
@@ -1810,11 +1810,20 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
1810
1810
|
|
|
1811
1811
|
// rc/alpha 兼容边界:原生 startSession 会复用工作区内的空白会话。
|
|
1812
1812
|
// 只在清洗会话激活时替换此动作,创建普通会话;不改 connectWorkspace 或全局点击。
|
|
1813
|
-
function installNewSessionBridge(ctx) {
|
|
1813
|
+
function installNewSessionBridge(ctx, navigation) {
|
|
1814
|
+
if (!navigation && typeof ctx.inject === 'function') {
|
|
1815
|
+
const legacy = typeof ctx.workspaces?.startSession === 'function'
|
|
1816
|
+
? installNewSessionBridge(ctx, ctx.workspaces) : () => {};
|
|
1817
|
+
const fiber = ctx.inject(['uiWorkspace'], scope => {
|
|
1818
|
+
scope.effect(() => installNewSessionBridge(scope, scope.uiWorkspace), 'data-cleaning-agent: native new session');
|
|
1819
|
+
});
|
|
1820
|
+
return () => { legacy(); fiber?.dispose?.(); };
|
|
1821
|
+
}
|
|
1814
1822
|
const workspaces = ctx.workspaces;
|
|
1815
|
-
|
|
1823
|
+
navigation = navigation || workspaces;
|
|
1824
|
+
const original = navigation?.startSession;
|
|
1816
1825
|
if (typeof original !== 'function' || typeof ctx.sessions?.create !== 'function') return () => {};
|
|
1817
|
-
const ownDescriptor = Object.getOwnPropertyDescriptor(
|
|
1826
|
+
const ownDescriptor = Object.getOwnPropertyDescriptor(navigation, 'startSession');
|
|
1818
1827
|
let pending = null;
|
|
1819
1828
|
let disposed = false;
|
|
1820
1829
|
const wrapped = function (workspaceId) {
|
|
@@ -1837,13 +1846,13 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
1837
1846
|
console.warn('[dc-agent] new session failed; current draft retained:', error instanceof Error ? error.message : String(error));
|
|
1838
1847
|
}).finally(() => { pending = null; });
|
|
1839
1848
|
};
|
|
1840
|
-
try {
|
|
1849
|
+
try { navigation.startSession = wrapped; }
|
|
1841
1850
|
catch (_error) { console.warn('[dc-agent] New Session compatibility bridge unavailable'); return () => {}; }
|
|
1842
1851
|
return () => {
|
|
1843
1852
|
disposed = true;
|
|
1844
|
-
if (
|
|
1845
|
-
if (ownDescriptor) Object.defineProperty(
|
|
1846
|
-
else delete
|
|
1853
|
+
if (navigation.startSession !== wrapped) return;
|
|
1854
|
+
if (ownDescriptor) Object.defineProperty(navigation, 'startSession', ownDescriptor);
|
|
1855
|
+
else delete navigation.startSession;
|
|
1847
1856
|
};
|
|
1848
1857
|
}
|
|
1849
1858
|
|
|
@@ -2102,7 +2111,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
2102
2111
|
'导入企业名单或图片,核验主体、补全字段,并导出可追溯结果。');
|
|
2103
2112
|
}
|
|
2104
2113
|
|
|
2105
|
-
function workflowNavigationIssue(step, task, hasData, profile, qccRun) {
|
|
2114
|
+
function workflowNavigationIssue(step, task, hasData, profile, qccRun, hasLocalResult = false) {
|
|
2106
2115
|
if (['upload', 'history'].includes(step)) return null;
|
|
2107
2116
|
if (step === 'download' && task?.artifacts?.length) return null;
|
|
2108
2117
|
if (!hasData) return '请先在「导入与核验」载入并核对完整名单。';
|
|
@@ -2116,6 +2125,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
2116
2125
|
if (step === 'enrich' && requiresQcc && !['matched', 'enriching', 'export_ready', 'completed', 'partial'].includes(task.state)) {
|
|
2117
2126
|
return '请先在「主体匹配」确认企业;多候选需要人工核验。';
|
|
2118
2127
|
}
|
|
2128
|
+
if (step === 'download' && !requiresQcc && hasLocalResult && ['rules_confirmed', 'diagnosed'].includes(task.state)) return null;
|
|
2119
2129
|
if (step === 'download' && !['export_ready', 'completed', 'partial'].includes(task.state) && !['completed', 'partial'].includes(qccRun?.state)) {
|
|
2120
2130
|
return '请先完成清洗或字段补全。原始清单可在「导入与核验」下载。';
|
|
2121
2131
|
}
|
|
@@ -4186,9 +4196,9 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
4186
4196
|
h('button', { type: 'button', className: 'dcAgentButton', 'aria-pressed': step === 'rules', onClick: () => actions.setStep('rules') }, '字段映射与规则'),
|
|
4187
4197
|
h('button', { type: 'button', className: 'dcAgentButton', 'aria-pressed': step === 'profile', onClick: () => actions.setStep('profile') }, '质量体检报告'),
|
|
4188
4198
|
) : null,
|
|
4189
|
-
workflowNavigationIssue(step, cachedTask, hasData, profile, qccRun)
|
|
4199
|
+
workflowNavigationIssue(step, cachedTask, hasData, profile, qccRun, Boolean((clean || complete) && exportRows()?.length))
|
|
4190
4200
|
? h('section', { className: 'dcAgentSection', role: 'status' },
|
|
4191
|
-
h('p', null, workflowNavigationIssue(step, cachedTask, hasData, profile, qccRun)),
|
|
4201
|
+
h('p', null, workflowNavigationIssue(step, cachedTask, hasData, profile, qccRun, Boolean((clean || complete) && exportRows()?.length))),
|
|
4192
4202
|
h('button', { type: 'button', className: 'dcAgentButton',
|
|
4193
4203
|
onClick: () => actions.setStep(!hasData ? 'upload' : !cachedTask || ['draft', 'uploaded'].includes(cachedTask.state) ? 'rules' : cachedTask.state === 'rules_confirmed' ? 'profile' : step === 'download' ? 'enrich' : 'match') }, '前往前置步骤'))
|
|
4194
4204
|
: pane,
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/** Read-only combination check. Never installs packages or reads profile secrets. */
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { resolve, dirname } from 'node:path';
|
|
4
|
+
import { createRequire } from 'node:module';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { execFileSync } from 'node:child_process';
|
|
7
|
+
|
|
8
|
+
export function assessCombination({ host, sidebar, context }) {
|
|
9
|
+
const errors = [], warnings = [];
|
|
10
|
+
if (host === '0.1.2-rc.1' && sidebar === '0.17.1') errors.push('DSH 0.1.2-rc.1 与 Better Sidebar 0.17.1 不兼容:缺少 settingsNamespace;请升级侧边栏到 0.18.1。');
|
|
11
|
+
if (!host) errors.push('无法识别实际 DSH CLI 版本;请先安装完整 DSH,再重新预检。');
|
|
12
|
+
if (sidebar === '0.18.1' && host && host !== '0.1.2-rc.1') {
|
|
13
|
+
if (['0.1.1-rc.2', '0.1.2-alpha.2'].includes(host)) {
|
|
14
|
+
errors.push('Better Sidebar 0.18.1 不兼容此旧宿主。备份后由宿主管理者升级完整 @deepseek-ai/dsh@0.1.2-rc.1;不要只升级 Session 子包。');
|
|
15
|
+
} else warnings.push('此宿主与 Better Sidebar 0.18.1 组合未验证。');
|
|
16
|
+
}
|
|
17
|
+
if (!sidebar) errors.push('工作台需要 dsh-better-sidebar;目标 Profile 请安装 0.18.1(需完整 DSH 0.1.2-rc.1)。');
|
|
18
|
+
else if (sidebar !== '0.18.1') warnings.push('此侧边栏版本未验证;仍需 targetedOpen 和 stateSubscription 能力。');
|
|
19
|
+
if (host === '0.1.2-rc.1' && context === '0.36.0') errors.push('已安装的 dsh-context 0.36.0 使用旧 settingsNamespace;先升级该插件到 0.48.0。context 并非本产品必装依赖。');
|
|
20
|
+
else if (context && context !== '0.48.0') warnings.push('已安装的 context 版本尚未做共存验证。');
|
|
21
|
+
if (host && host !== '0.1.2-rc.1' && !warnings.length && !errors.length) warnings.push('此宿主组合未验证。');
|
|
22
|
+
return { host, sidebar, context, errors, warnings, ok: errors.length === 0 };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function inspectProfile(profile, host) {
|
|
26
|
+
const req = createRequire(resolve(profile, 'package.json'));
|
|
27
|
+
const version = name => {
|
|
28
|
+
let path;
|
|
29
|
+
try { path = req.resolve(`${name}/package.json`); }
|
|
30
|
+
catch { try { path = req.resolve(name); } catch { return null; } }
|
|
31
|
+
for (let dir = dirname(path); ; dir = dirname(dir)) {
|
|
32
|
+
try { const pkg = JSON.parse(readFileSync(resolve(dir, 'package.json'), 'utf8')); if (pkg.name === name) return pkg.version; } catch { /* no manifest here */ }
|
|
33
|
+
if (dirname(dir) === dir) return null;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
return assessCombination({ host, sidebar: version('dsh-better-sidebar'), context: version('dsh-context') });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
40
|
+
const profile = process.argv[2];
|
|
41
|
+
if (!profile) { console.error('Usage: node lib/install-preflight.js <profile-directory> [dsh-executable]'); process.exitCode = 2; }
|
|
42
|
+
else {
|
|
43
|
+
let host = null;
|
|
44
|
+
try { host = execFileSync(process.argv[3] || 'dsh', ['--version'], { encoding: 'utf8', timeout: 15000 }).match(/\b\d+\.\d+\.\d+(?:-[\w.]+)?\b/)?.[0] ?? null; } catch { /* reported below */ }
|
|
45
|
+
const report = inspectProfile(profile, host);
|
|
46
|
+
console.log(JSON.stringify(report, null, 2));
|
|
47
|
+
process.exitCode = report.ok ? 0 : 1;
|
|
48
|
+
}
|
|
49
|
+
}
|
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.1",
|
|
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",
|