dsh-data-cleaning-agent 0.2.0 → 0.3.0

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
@@ -4,8 +4,23 @@
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.3.0] - 2026-09-01
8
+
9
+ > 企查查 MCP 接入 · 方案 A(模型中介式企业名单补全)首个版本。
10
+
7
11
  ### Added
8
- - 开源社区化工程骨架(README 双语、LICENSE、CONTRIBUTING、install.sh、marketing 元数据、CI/Release workflow)。
12
+ - 内嵌 Skill `enterprise-enrichment`(`lib/skill-enrich.js`):引导模型复用
13
+ `qcc-dsh-mcp-oauth` 已上架的工具面(`qcc_oauth_status` / `mcp__qcc-company__*` /
14
+ `mcp__qcc-risk__*`),逐个企业完成「消歧 → 工商详情 → 风险标签」补全。
15
+ - `docs/QCC-ENRICHMENT-DESIGN.md`:QCC 能力设计(方案 A 模型中介式 + v1 字段契约)。
16
+ - 文档:`docs/USER-GUIDE.md` 增补企业名单补全一节;`docs/COMPATIBILITY.md` 补共存说明。
17
+
18
+ ## [0.2.1] - 2026-09-01
19
+
20
+ > OIDC 可信发布链路验证版本,无功能变更。
21
+
22
+ ### Changed
23
+ - 发布流程:接入 npm OIDC Trusted Publishing(`release.yml` + `--provenance`),`v*` tag 自动发布并生成 GitHub Release。
9
24
 
10
25
  ## [0.2.0] - 2026-09-01
11
26
 
@@ -13,6 +28,7 @@
13
28
  > 以便社区 fork / PR / npm 公开安装。
14
29
 
15
30
  ### Added
31
+ - 开源社区化工程骨架(README 双语、LICENSE、CONTRIBUTING、install.sh、marketing 元数据、CI/Release workflow)。
16
32
  - MVP 全量能力:CSV/XLSX/JSON 解析、清洗(trim / 手机号规范化 / 缺失剔除 / 负金额剔除 / 去重)、
17
33
  确定性补全、概览画像、CSV 回写(`lib/engine.js`)。
18
34
  - 三个模型工具:`data_clean_rows` / `data_complete_rows` / `data_profile`(`lib/tools.js`)。
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 version / 当前版本: **0.2.0**
5
+ > Current version / 当前版本: **0.3.0**
6
6
 
7
7
  [![CI](https://github.com/duhu2000/dsh-data-cleaning-agent/actions/workflows/ci.yml/badge.svg)](https://github.com/duhu2000/dsh-data-cleaning-agent/actions/workflows/ci.yml)
8
8
  [![npm](https://img.shields.io/npm/v/dsh-data-cleaning-agent)](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 version: **0.2.0**
5
+ > 当前版本 / Current version: **0.3.0**
6
6
 
7
7
  [![CI](https://github.com/duhu2000/dsh-data-cleaning-agent/actions/workflows/ci.yml/badge.svg)](https://github.com/duhu2000/dsh-data-cleaning-agent/actions/workflows/ci.yml)
8
8
  [![npm](https://img.shields.io/npm/v/dsh-data-cleaning-agent)](https://www.npmjs.com/package/dsh-data-cleaning-agent)
@@ -30,13 +30,20 @@
30
30
  | web 路由 | `webServer.register({kind:'prefix', path, handler})` | 最长前缀匹配;前缀需以 `/` 结尾且匹配 `pathname.startsWith(prefix + '/')` |
31
31
  | 同源守卫 | `isTrusted(req)` | `sec-fetch-site !== 'cross-site'` 且 origin 为 127.0.0.1/localhost |
32
32
 
33
- ## 4. 与企查查 MCP OAuth 插件的共存(规划)
33
+ ## 4. 与企查查 MCP OAuth 插件的共存
34
34
 
35
35
  | | `qcc-dsh-mcp-oauth` | 本插件 |
36
36
  | --- | --- | --- |
37
37
  | 工具名前缀 | `qcc_oauth_*` + `mcp__qcc-*` | `data_clean_rows` / `data_complete_rows` / `data_profile` |
38
+ | Skill | — | `data-cleaning`、`enterprise-enrichment` |
38
39
  | 存储域 | 自有 grant store | `dc_tasks_v1` |
39
- | 能否共存 | ✅ | ✅(工具名 / 存储域 / 条目 id 全独立) |
40
+ | 能否共存 | ✅ | ✅(工具名 / Skill 名 / 存储域 / 条目 id 全独立) |
41
+
42
+ - `enterprise-enrichment` Skill 本身**不重造 OAuth**:它只调用
43
+ `qcc_oauth_status` / `qcc_oauth_connect`(由 qcc-dsh-mcp-oauth 提供)与
44
+ `mcp__qcc-company__*` / `mcp__qcc-risk__*`(授权成功后由 mcp-client 动态提供)。
45
+ - 若 qcc-dsh-mcp-oauth 未安装或未授权,`enterprise-enrichment` Skill 的第一步
46
+ `qcc_oauth_status` 即会中断并引导用户先连接,不会假装补全。
40
47
 
41
48
  ## 5. 已知限制
42
49
 
@@ -0,0 +1,238 @@
1
+ # QCC 能力设计:企业名单补全(G4 · 方案 A 模型中介式)
2
+
3
+ > 状态:设计稿(待评审通过后实施)
4
+ > 日期:2026-09-01
5
+ > 关联:`docs/PLAN-OSS.md` §8(Phase 2 接入规划)
6
+ > 决策:先做 **方案 A(模型中介式,快、可发布)**;同阶段开 **Spike #7** 验证方案 B 的程序化调用面。
7
+ > 范围:本文档只设计 G4(方案 A)。方案 B(`lib/qcc.js` 后台批量)见 Spike #7 另行设计。
8
+
9
+ ---
10
+
11
+ ## 1. 目标与非目标
12
+
13
+ ### 1.1 目标
14
+
15
+ 让"数据清洗补全智能体"在**已连接企查查 MCP** 的前提下,把一批**企业名单**
16
+ (只有企业名,或企业名 + 少量残缺字段)补全为带最新工商信息的结构化名单:
17
+
18
+ ```
19
+ 输入:企业名(必填,支持模糊名/简称)
20
+ 输出:credit_no / legal_rep / reg_capital / establish_date /
21
+ reg_status / biz_status / risk_tags
22
+ ```
23
+
24
+ ### 1.2 非目标(本次不做)
25
+
26
+ - **不重造 OAuth**:完全复用 `qcc-dsh-mcp-oauth` 已上架的授权与工具面
27
+ (`qcc_oauth_connect` / `mcp__qcc-company__*` / `mcp__qcc-risk__*`)。
28
+ - **不做后台程序化批量**(方案 B):模型中介式就是让模型亲自调 QCC 工具,
29
+ 本插件不新增 `lib/qcc.js`、不直接调用 mcp-client 服务。
30
+ - **不改现有清洗/补全/概览引擎**:`data_clean_rows` / `data_complete_rows` /
31
+ `data_profile` 的确定性语义保持原样;企业补全作为**新 Skill + 新流程**叠加,不污染旧路径。
32
+
33
+ ---
34
+
35
+ ## 2. 复用机制与工具契约
36
+
37
+ ### 2.1 依赖的已上架插件
38
+
39
+ | 插件 | npm 包 | 提供的工具面 | 与本插件关系 |
40
+ | --- | --- | --- | --- |
41
+ | 企查查 MCP OAuth | `qcc-dsh-mcp-oauth` | `qcc_oauth_connect/status/disconnect` + `mcp__qcc-company__*` + `mcp__qcc-risk__*` | **前置依赖**:用户先连企查查,本插件才有数据源 |
42
+
43
+ 共存约束(已写入 `docs/COMPATIBILITY.md`):
44
+
45
+ | | qcc-dsh-mcp-oauth | 本插件(数据清洗) |
46
+ | --- | --- | --- |
47
+ | 工具名前缀 | `qcc_oauth_*` + `mcp__qcc-*` | `data_clean_rows` / `data_complete_rows` / `data_profile` |
48
+ | 存储域 | 自有 grant store | `dc_tasks_v1` |
49
+ | 能否共存 | ✅ 工具名/存储域/条目 id 全独立 | ✅ |
50
+
51
+ ### 2.2 方案 A 用到的 QCC 工具(真实工具名)
52
+
53
+ | 步骤 | 工具 | 用途 |
54
+ | --- | --- | --- |
55
+ | 1. 消歧 | `mcp__qcc-company__get_company_by_query` | 企业名 → 唯一精确匹配(自动锁定,带统一社会信用代码)或多候选(最多 5 个) |
56
+ | 2. 工商详情 | `mcp__qcc-company__get_company_registration_info` | 用锁定实体(名称或统一社会信用代码)取法定代表人/注册资本/成立日期/登记状态等 |
57
+ | 3. 风险标签 | `mcp__qcc-risk__get_company_risk_scan` | 用锁定实体取 35 项风险因子计数(失信/被执行/裁判文书/行政处罚/股权冻结…) |
58
+
59
+ > 字段名以 QCC MCP 工具**实际返回**为准,实施时逐字段核对;本文档用概念名
60
+ > (`creditNo`/`legalRep`/`regCapital`/`establishDate`/`regStatus`/`bizStatus`)
61
+ > 表达契约,落地时映射到工具真实字段。
62
+
63
+ ---
64
+
65
+ ## 3. 数据路径
66
+
67
+ ```
68
+ 用户:帮我补全这份企业名单(CSV/JSON/文本,或直接给企业名列表)
69
+
70
+ ├─ 模型解析名单(可复用现有 data_profile 概览 + 本地解析)
71
+
72
+ ├─ 模型确认「已连接企查查」:
73
+ │ 调 qcc_oauth_status;或发现 mcp__qcc-company__* 工具存在
74
+
75
+ ├─ 对每个企业名:
76
+ │ mcp__qcc-company__get_company_by_query(name)
77
+ │ └─ 唯一精确匹配 → 锁定实体(creditNo)
78
+ │ └─ 多候选 → 暂停,交用户确认(禁止自动取第一名,见 §6)
79
+ │ mcp__qcc-company__get_company_registration_info(锁定实体)
80
+ │ mcp__qcc-risk__get_company_risk_scan(锁定实体) [可选,取风险标签]
81
+
82
+ ├─ 模型把 QCC 返回字段按 §5 契约组装为结构化行
83
+
84
+ └─ 产出:补全后的名单(对话摘要 + 可下载 CSV)
85
+ 明细经同源 web 下载链路交付,不把完整明细直接吐回对话(沿用现有安全边界)
86
+ ```
87
+
88
+ 关键点:**QCC 调用是模型亲自完成的**(模型 → MCP 工具 → 模型),本插件只提供
89
+ (1)名单解析与(2)结果写回/下载,(3)Skill 工作流指引。这正好落在
90
+ "数据由模型组装"的既有边界内,零后端改造。
91
+
92
+ ---
93
+
94
+ ## 4. Skill 设计
95
+
96
+ ### 4.1 方案:新增 `enterprise-enrichment` Skill(不改 `data-cleaning`)
97
+
98
+ - 现有 `data-cleaning` Skill 语义是"确定性清洗/补全/概览",不应混入"外部工商数据补全"
99
+ (职责不同、失败模式不同、依赖不同)。
100
+ - 新增 Skill `enterprise-enrichment`,触发语:用户说"补全企业名单""补齐工商信息"
101
+ "用企查查补全""查一下这些公司的统一社会信用代码/法人/注册资本"等。
102
+
103
+ ### 4.2 Skill 内容草案
104
+
105
+ ```text
106
+ name: enterprise-enrichment
107
+ description: Enrich a list of company names with the latest Qichacha (QCC)
108
+ business-registration fields via the QCC MCP tools.
109
+ whenToUse: When the user gives a list of company names (possibly incomplete or
110
+ fuzzy) and asks to fill in credit code / legal representative / registered
111
+ capital / establishment date / registration & business status / risk tags,
112
+ or to "enrich / complete with Qichacha".
113
+ source: dsh-data-cleaning-agent
114
+ content:
115
+ - Workflow:
116
+ 1. Detect QCC availability: run `qcc_oauth_status`. If not connected,
117
+ tell the user to run `qcc_oauth_connect` first, and stop.
118
+ 2. Parse the company-name list (from pasted text / CSV / JSON). Keep only
119
+ the distinct company-name column.
120
+ 3. For EACH name: `mcp__qcc-company__get_company_by_query`.
121
+ - unique exact match → lock the entity (use its credit code).
122
+ - multiple candidates → DO NOT auto-pick the first; show the candidates
123
+ (name + region + credit code) and ask the user which one.
124
+ - no match → mark that row as `unresolved` and continue.
125
+ 4. For each locked entity: `mcp__qcc-company__get_company_registration_info`
126
+ (fill credit_no / legal_rep / reg_capital / establish_date / reg_status /
127
+ biz_status) and, when risk tags are wanted,
128
+ `mcp__qcc-risk__get_company_risk_scan` (fill risk_tags).
129
+ 5. Assemble the enriched table. NEVER invent a field — if QCC returns no
130
+ value, leave it empty and mark the row/field as unresolved.
131
+ 6. Report only a summary (enriched N / unresolved M / multi-candidate K)
132
+ plus the enriched CSV via the download link. Never dump full detail rows
133
+ into the chat.
134
+ - Safety rules:
135
+ - Never fabricate a credit code, legal rep, capital, or status.
136
+ - Never auto-select among ambiguous candidates.
137
+ - Never expose QCC tokens or credentials.
138
+ ```
139
+
140
+ > 具体措辞在实施时打磨,并与 QCC OAuth 插件的 `qcc_oauth_connect` 引导语对齐。
141
+
142
+ ### 4.3 是否新增模型工具
143
+
144
+ 方案 A 可做到**零新工具**(模型直接调 QCC 工具 + 复用现有 web 解析/下载)。
145
+ 可选加一个轻量工具 `data_rows_to_csv`(把模型组装的补全行数组 → CSV 下载链接),
146
+ 避免模型手拼 CSV。**实施时评估**:若模型拼 CSV 易错,再加;否则不加,保持零后端改动。
147
+
148
+ ---
149
+
150
+ ## 5. v1 字段契约与映射表
151
+
152
+ | 输出字段 | 中文 | 来源工具 | 备注 |
153
+ | --- | --- | --- | --- |
154
+ | `credit_no` | 统一社会信用代码 | `get_company_by_query` 锁定实体时带回 / `get_company_registration_info` | 消歧成功即有 |
155
+ | `legal_rep` | 法定代表人 | `get_company_registration_info` | 缺失留空 + 标记 |
156
+ | `reg_capital` | 注册资本 | `get_company_registration_info` | 原样引用,不四舍五入 |
157
+ | `establish_date` | 成立日期 | `get_company_registration_info` | 原样引用 |
158
+ | `reg_status` | 登记状态 | `get_company_registration_info` | 原样引用(存续/在业/吊销/注销…) |
159
+ | `biz_status` | 经营状态 | `get_company_registration_info`(若含)/ `get_company_profile` 兜底 | 实施时核对字段落点 |
160
+ | `risk_tags` | 风险标签 | `get_company_risk_scan`(35 项计数中命中项) | 仅陈述"命中维度+计数",不下定性结论 |
161
+
162
+ > 对齐 QCC 工具的数据纪律:金额/比例/计数一律**逐字引用工具返回值**,
163
+ > 禁止模型自行相加、相乘或估算;聚合/穿透值以工具返回为准。
164
+
165
+ ---
166
+
167
+ ## 6. 消歧与安全策略
168
+
169
+ 1. **多候选必须交用户确认**:`get_company_by_query` 返回 >1 候选时,模型列出候选
170
+ (企业名 + 地区 + 统一社会信用代码),等待用户选定,**禁止自动取排名第一**。
171
+ - 这是 QCC 工具契约的硬性要求(错误选择会对错误主体做补全)。
172
+ 2. **模糊名先行提示**:对明显残缺/简称的名称,先提示用户补充地区等线索,
173
+ 减少多候选与错配。
174
+ 3. **不编造**:QCC 未返回值 → 留空 + `unresolved`,绝不占位编造。
175
+ 4. **凭据安全**:整个流程不接触、不回显 QCC token;token 只存在于 qcc-mcp-oauth
176
+ 自己的 grant store,本插件不读它。
177
+ 5. **数据边界**:完整明细经同源 web 下载交付(沿用 `isTrusted` + `no-store` 响应头),
178
+ 对话内只给摘要 + 下载链接。
179
+
180
+ ---
181
+
182
+ ## 7. 未连接企查查时的引导路径
183
+
184
+ - Skill 第一步 `qcc_oauth_status`:
185
+ - **未连接** → 模型告知用户先运行 `qcc_oauth_connect`(QCC OAuth 插件提供),并停止补全。
186
+ - **已连接但 token 过期** → 引导 `qcc_oauth_connect`(OAuth 插件会复用授权自动刷新,不重复弹授权页)。
187
+ - **已连接** → 继续。
188
+ - 兜底:若模型在未连接时直接调 `mcp__qcc-company__*`,QCC MCP 工具会返回
189
+ 未授权错误(401 语义),Skill 的失败处理同样引导到 `qcc_oauth_connect`。
190
+
191
+ ---
192
+
193
+ ## 8. 验收 Gate(G4 达成标准)
194
+
195
+ 1. **双基线 headless 真实模型**:给一段企业名单(含 1 个精确名 + 1 个模糊名 + 1 个多候选名),
196
+ 在已连接企查查的环境下,模型按 Skill 完成:
197
+ - 精确名 → 工商字段回填正确;
198
+ - 多候选名 → 模型停下询问而非乱选;
199
+ - 未命中名 → `unresolved` 标记。
200
+ 2. **未连接环境**:模型第一步即引导 `qcc_oauth_connect` 并停止,不假装补全。
201
+ 3. **安全回归**:`npm run check` 全绿;现有 13 例引擎测试不受影响;
202
+ 补全明细只经下载链路交付,对话内无完整明细泄露。
203
+ 4. **文档同步**:`docs/USER-GUIDE.md` 增补"企业名单补全"一节;
204
+ `docs/COMPATIBILITY.md` 的共存表若缺 `enterprise-enrichment` 技能则补上。
205
+
206
+ ---
207
+
208
+ ## 9. 与方案 B 的边界与预留
209
+
210
+ - 方案 A 不改 `lib/`(最多可选加 `data_rows_to_csv` 工具)。
211
+ - 方案 B 新增 `lib/qcc.js`(host 半区程序化调用 mcp-client),依赖 Spike #7 验证
212
+ `ctx.loader` 条目能否被插件代码直接 `tools/call`。
213
+ - 两者**共享**:§5 字段契约、§6 消歧策略、§7 未连接引导。方案 B 落地时直接复用,
214
+ 不重定义契约。
215
+
216
+ ---
217
+
218
+ ## 10. 实施变更清单(评审通过后执行)
219
+
220
+ | # | 变更 | 文件 | 可逆 |
221
+ | --- | --- | --- | --- |
222
+ | 1 | 新增 `enterprise-enrichment` Skill | `lib/skill.js`(或新 `lib/skill-enrich.js`) | ✅ 本地 |
223
+ | 2 | (可选)新增 `data_rows_to_csv` 工具 | `lib/tools.js` | ✅ 本地 |
224
+ | 3 | `docs/USER-GUIDE.md` 增补企业名单补全一节 | `docs/USER-GUIDE.md` | ✅ 本地 |
225
+ | 4 | `docs/COMPATIBILITY.md` 补共存说明 | `docs/COMPATIBILITY.md` | ✅ 本地 |
226
+ | 5 | `npm run check` + 双基线 headless 真实模型验收 | — | ✅ 本地 |
227
+ | 6 | 版本号 bump + CHANGELOG + README 版本同步 | 多文件 | ✅ 本地 |
228
+ | 7 | tag → OIDC 自动发布(已跑通链路) | — | ⚠️ 外发,需授权 |
229
+
230
+ ---
231
+
232
+ ## 11. 风险
233
+
234
+ 1. **名单大时 token 消耗大、逐条慢**:方案 A 是逐企业调用 QCC 工具,百级名单成本高;
235
+ → Skill 里写明批处理节奏(一次一批,批间汇报进度);百级以上建议走方案 B。
236
+ 2. **多候选误配**:靠 §6 的"必须确认"策略兜底,但模型可能未遵守;
237
+ → Skill 强调 + 验收用例覆盖。
238
+ 3. **QCC 工具字段名漂移**:本文档用概念名,落地时以工具真实返回为准并冻结到实现里。
@@ -0,0 +1,232 @@
1
+ # 企查查数据维度补全 · 二期 / 三期路线图与字段清单
2
+
3
+ > 本文档是 `dsh-data-cleaning-agent` 接入企查查(QCC)MCP 的**分期规划与可清洗/补全维度字段清单**。
4
+ > 一期(方案 A 模型中介式,已落地于 0.3.0)见 [QCC-ENRICHMENT-DESIGN.md](QCC-ENRICHMENT-DESIGN.md)。
5
+
6
+ ## 0. 工具面口径
7
+
8
+ 企查查 MCP 当前按 **6 大资源域** 暴露数据工具,**合计 185 个**(16 + 38 + 18 + 35 + 34 + 44 = 185),
9
+ 另加招投标附加域 6 个:
10
+
11
+ | 资源域 | MCP 前缀 | 工具数 | 授权要求 | 数据主题 |
12
+ | --- | --- | --- | --- | --- |
13
+ | 工商 | `mcp__qcc-company__*` | 16 | 基础授权 | 主体、股权、人员、财务、上市 |
14
+ | 风险 | `mcp__qcc-risk__*` | 38 | 基础授权 | 司法、失信、执行、处罚、冻结 |
15
+ | 知产 | `mcp__qcc-ipr__*` | 18 | 基础授权 | 专利、商标、软著、数字资产 |
16
+ | 经营 | `mcp__qcc-operation__*` | 35 | 基础授权 | 资质、招投标、融资、舆情、监管 |
17
+ | 历史 | `mcp__qcc-history__*` | 34 | **企业认证账号** | 历史股东/法人/变更/风险 |
18
+ | 人员 | `mcp__qcc-executive__*` | 44 | 基础授权 | 董监高个人风险与关联 |
19
+ | 招投标(附加) | `mcp__qcc-tender__*` | 6 | 基础授权 | 标讯、拟建项目、企业标讯画像 |
20
+
21
+ > 6 大资源域恰好 185 个;招投标域为附加能力。实际可用工具数随授权资源域(`QCC_RESOURCES`)
22
+ > 与账号等级变化。各工具的具体输入输出字段以官方 MCP 工具 schema 为准,本文只列
23
+ > 「补全维度 → 关键字段 → 来源工具」的映射。
24
+
25
+ ---
26
+
27
+ ## 1. 分期总览
28
+
29
+ | 阶段 | 版本 | 交付形态 | 覆盖维度 | 依赖 |
30
+ | --- | --- | --- | --- | --- |
31
+ | 一期 | 0.3.0 ✅ | 方案 A:模型中介式 Skill `enterprise-enrichment` | 核心工商 7 字段 + 风险标签 | `qcc-dsh-mcp-oauth` 已连接 |
32
+ | 二期 | 0.4.0 | 方案 A 扩展 Skill:工商全景 + 股权穿透 | 工商域 16 工具 + 历史工商 | 同上 |
33
+ | 三期 | 0.5.0 | 方案 A 扩展 Skill:风险/知产/经营 + 方案 B 批量后端 | 风险 38 + 知产 18 + 经营 35 | 同上 + Spike #7(`ctx.loader` 可调) |
34
+ | 四期(可选) | 0.6.0 | 历史轨迹 + 董监高 + 招投标 | 历史 34 + 人员 44 + 招投标 6 | 企业认证账号(历史域) |
35
+
36
+ 每期之间不互相阻塞:二期工商全景、三期风险知产都可独立评审与合入。
37
+
38
+ ---
39
+
40
+ ## 2. 一期(0.3.0,已落地)· 核心工商字段
41
+
42
+ v1 字段契约(方案 A):
43
+
44
+ | 字段 | 含义 | 来源工具 |
45
+ | --- | --- | --- |
46
+ | `credit_no` | 统一社会信用代码 | `mcp__qcc-company__get_company_registration_info` |
47
+ | `legal_rep` | 法定代表人 | 同上 |
48
+ | `reg_capital` | 注册资本 | 同上 |
49
+ | `establish_date` | 成立日期 | 同上 |
50
+ | `reg_status` | 登记状态 | 同上 |
51
+ | `biz_status` | 经营状态 | 同上 |
52
+ | `risk_tags` | 风险标签(命中维度 + 计数) | `mcp__qcc-risk__get_company_risk_scan` |
53
+
54
+ ---
55
+
56
+ ## 3. 二期(0.4.0)· 工商全景 + 股权穿透
57
+
58
+ 目标:把「只补身份证」升级为「补全家福」——主体详情、股权结构、对外投资、人员、财务、上市、
59
+ 联系方式、开票信息,以及历史工商沿革(历史域)。
60
+
61
+ ### 3.1 工商域(`mcp__qcc-company__*`)
62
+
63
+ | 补全维度 | 关键字段 | 来源工具 |
64
+ | --- | --- | --- |
65
+ | 主体锚定 | 企业名、统一社会信用代码、注册号 | `get_company_by_query` / `get_company_registration_info` |
66
+ | 企业画像 | 简介、行业、产业链 | `get_company_profile` |
67
+ | 二要素核验 | 名称 ↔ 信用代码是否一致 | `verify_company_accuracy` |
68
+ | 实控人 | 总持股比例、表决权比例、最终受益股份 | `get_actual_controller` |
69
+ | 受益所有人 | UBO 识别(央行口径) | `get_beneficial_owners` |
70
+ | 股东构成 | 股东名、持股比例、认缴出资额、出资时间 | `get_shareholder_info` |
71
+ | 对外投资 | 被投企业、持股比例、认缴额 | `get_external_investments` |
72
+ | 分支机构 | 机构名、负责人、地区、状态 | `get_branches` |
73
+ | 主要人员 | 姓名、职务(董监高) | `get_key_personnel` |
74
+ | 变更记录 | 变更事项、前后值、日期 | `get_change_records` |
75
+ | 年报 | 报告年度、从业人数、资产/营收 | `get_annual_reports` |
76
+ | 联系方式 | 电话、邮箱、网站、ICP 备案 | `get_contact_info` |
77
+ | 开票信息 | 税号、地址、开户行 | `get_tax_invoice_info` |
78
+ | 上市信息 | 代码、简称、交易所、市值 | `get_listing_info` |
79
+ | 财务数据 | 营收、利润、资产负债率、增长率 | `get_financial_data` |
80
+
81
+ ### 3.2 历史工商(`mcp__qcc-history__*`,需企业认证账号)
82
+
83
+ | 补全维度 | 关键字段 | 来源工具 |
84
+ | --- | --- | --- |
85
+ | 历史股东 | 曾持股比例、退出日期 | `get_historical_shareholders` |
86
+ | 历史法人 | 历任法代、任职起止 | `get_historical_legal_rep` |
87
+ | 历史高管 | 历任高管、任职起止 | `get_historical_executives` |
88
+ | 历史登记 | 曾用名、历史注册资本/地址/经营范围 | `get_historical_registration` |
89
+
90
+ ### 3.3 二期验收门
91
+
92
+ - Skill 对一份 20 条企业名单,能在二期字段契约内输出**每企业 ≥ 15 个维度**的补全表。
93
+ - 消歧规则不变(`get_company_by_query` 多候选必须询问用户)。
94
+ - 金额/比例/计数逐字引用工具返回值,禁止自算、禁止臆测。
95
+
96
+ ---
97
+
98
+ ## 4. 三期(0.5.0)· 风险 / 知产 / 经营 + 批量后端
99
+
100
+ 目标:覆盖风控名单、供应商尽调、招投标核查三类场景;同时启动方案 B 批量后端。
101
+
102
+ ### 4.1 风险域(`mcp__qcc-risk__*`,38 工具)
103
+
104
+ | 补全维度 | 关键字段 | 来源工具 |
105
+ | --- | --- | --- |
106
+ | 风险总览 | 35 项因子命中计数 | `get_company_risk_scan` |
107
+ | 关联风险 | 股东/投资/法人等关联方命中 | `get_company_related_risk_scan` |
108
+ | 行政处罚 | 处罚结果、金额、机关、日期 | `get_administrative_penalty` |
109
+ | 环保处罚 | 处罚结果、金额、机关 | `get_environmental_penalty` |
110
+ | 经营异常 | 列入原因、日期、决定机关 | `get_business_exception` |
111
+ | 严重违法 | 列入原因、日期、移出 | `get_serious_violation` |
112
+ | 失信被执行人 | 案号、金额、法院、日期 | `get_dishonest_info` |
113
+ | 被执行人 | 案号、执行标的、法院 | `get_judgment_debtor_info` |
114
+ | 终本案件 | 案号、终本日期、未履行金额 | `get_terminated_cases` |
115
+ | 限制高消费 | 案号、申请人、对象 | `get_high_consumption_restriction` |
116
+ | 股权冻结 | 股权数额、法院、期限 | `get_equity_freeze` |
117
+ | 股权出质 | 出质人、质权人、数额 | `get_equity_pledge_info` |
118
+ | 动产/土地抵押 | 抵押物、担保债权额、抵押权人 | `get_chattel_mortgage_info` / `get_land_mortgage_info` |
119
+ | 破产重整 | 案号、申请人、被申请人 | `get_bankruptcy_reorganization` |
120
+ | 立案信息 | 案号、案由、当事人 | `get_case_filing_info` |
121
+ | 开庭公告 | 案号、案由、开庭时间 | `get_hearing_notice` |
122
+ | 法院公告/送达 | 公告类型、案号、当事人 | `get_court_notice` / `get_service_notice` |
123
+ | 裁判文书 | 文书 ID、标题、案由、金额 | `get_judicial_documents`(详情 `get_judicial_document_detail`) |
124
+ | 欠税/税收违法 | 税种、金额、机关 | `get_tax_arrears_notice` / `get_tax_violation` / `get_tax_abnormal` |
125
+ | 违约 | 债券/票据/非标违约本金利息 | `get_default_info` |
126
+ | 担保/惩戒/限出境 | 担保金额、惩戒类型、案号 | `get_guarantee_info` / `get_disciplinary_list` / `get_exit_restriction` |
127
+ | 司法拍卖/悬赏/询价 | 起拍价、案号、财产 | `get_judicial_auction` / `get_property_asset_announcement` / `get_valuation_inquiry` |
128
+ | 诉前调解/公示催告/清算/注销 | 案号、案由、状态 | `get_pre_litigation_mediation` / `get_public_exhortation` / `get_liquidation_info` / `get_cancellation_record_info` / `get_simple_cancellation_info` / `get_service_announcement` |
129
+
130
+ ### 4.2 知产域(`mcp__qcc-ipr__*`,18 工具)
131
+
132
+ | 补全维度 | 关键字段 | 来源工具 |
133
+ | --- | --- | --- |
134
+ | 专利 | 专利名、类型、法律状态、申请日 | `get_patent_info` |
135
+ | 国际专利 | 发明名、公开号、发明人 | `get_international_patent` |
136
+ | 商标 | 商标名、类别、状态 | `get_trademark_info` |
137
+ | 商标文书 | 文书号、申请人、被申请人 | `get_trademark_document` |
138
+ | 软著 | 软件名、版本、登记号 | `get_software_copyright_info` |
139
+ | 作品著作权 | 作品名、登记号 | `get_copyright_work_info` |
140
+ | 标准 | 标准名、编号 | `get_standard_info` |
141
+ | 知产出质 | 出质类型、名称、期限 | `get_ipr_pledge` |
142
+ | 集成电路布图 | 布图名、登记号 | `get_integrated_circuit_layout` |
143
+ | 数字资产 | APP / 小程序 / 公众号 / 抖音 / 快手 / 微博 / 网店 | `get_app_info` / `get_mini_program` / `get_wechat_official_account` / `get_douyin_account` / `get_kuaishou_account` / `get_weibo_account` / `get_online_store` |
144
+ | 备案 | ICP/APP/小程序/算法备案 | `get_internet_service_info` |
145
+ | 特许经营 | 备案号、特许人 | `get_commercial_franchise` |
146
+
147
+ ### 4.3 经营域(`mcp__qcc-operation__*`,35 工具)
148
+
149
+ | 补全维度 | 关键字段 | 来源工具 |
150
+ | --- | --- | --- |
151
+ | 行政许可 | 许可证名称、编号、有效期 | `get_administrative_license` |
152
+ | 资质证书 | 证书类型、等级、状态 | `get_qualifications` |
153
+ | 纳税资质 | 纳税人类型、税务机关 | `get_taxpayer_qualification` |
154
+ | 信用评价 | 纳税信用、海关信用等级 | `get_credit_evaluation` |
155
+ | 信用承诺 | 类型、履行状态 | `get_credit_commitments` |
156
+ | 荣誉/榜单 | 荣誉名、榜单名、排名 | `get_honor_info` / `get_ranking_list_info` |
157
+ | 招投标 | 项目名、角色、金额 | `get_bidding_info` |
158
+ | 融资记录 | 轮次、金额、时间 | `get_financing_records` |
159
+ | 融资租赁 | 出租/承租、租赁价值 | `get_financing_lease_info` |
160
+ | 私募基金 | 管理人编号、规模区间 | `get_private_fund_manager` |
161
+ | 投资机构 | 机构类型、管理规模 | `get_investment_institution` |
162
+ | 上市公告 | 公告标题、类型、日期 | `get_company_announcement` / `get_related_announcement` |
163
+ | 舆情 | 新闻标题、情感倾向、时间 | `get_news_sentiment` |
164
+ | 政府约谈/公告 | 约谈问题、机关、日期 | `get_government_interview` / `get_government_announcement` |
165
+ | 监管抽查 | 抽查事项、结果、机关 | `get_random_check` / `get_spot_check_info` / `get_product_spot_check` |
166
+ | 食品安全 | 抽检结果、生产商 | `get_food_safety` |
167
+ | 违规通报 | 软件/化妆品/未准入境/召回 | `get_software_violation` / `get_counterfeit_cosmetics` / `get_entry_denied` / `get_product_recall` |
168
+ | 进出口信用 | 信用等级、备案 | `get_import_export_credit` |
169
+ | 土地/产权 | 受让/转让/产权交易 | `get_land_grant_info` / `get_land_transfer_info` / `get_property_rights_transaction` |
170
+ | 电信/游戏/广告 | 许可、版号、审查 | `get_telecom_license` / `get_game_approval` / `get_advertising_review` |
171
+ | 科技成果 | 成果名、登记号 | `get_tech_achievement` |
172
+ | 资产拍卖/招聘 | 起拍价、职位、薪酬 | `get_asset_auction` / `get_recruitment_info` |
173
+
174
+ ### 4.4 三期并行 · 方案 B 批量后端
175
+
176
+ 一期/二期/三期均为模型中介式(模型逐个调 QCC 工具)。当名单规模进入百级/千级,模型逐调成本高,
177
+ 启动方案 B(插件内 `lib/qcc.js` 直接经 `ctx.loader` 调用 mcp-client 条目):
178
+ - 前置:Spike #7 验证「`ctx.loader` 拿到的 mcp-client 条目可在插件后端直接调用」。
179
+ - 若验证失败,方案 B 边界封闭,退回方案 A 的分批模型中介。
180
+
181
+ ---
182
+
183
+ ## 5. 四期(0.6.0,可选)· 历史轨迹 + 董监高 + 招投标
184
+
185
+ ### 5.1 人员域(`mcp__qcc-executive__*`,44 工具)
186
+
187
+ | 补全维度 | 关键字段 | 来源工具 |
188
+ | --- | --- | --- |
189
+ | 个人风险总览 | 18 项命中计数 | `get_executive_risk_scan` |
190
+ | 关联企业风险 | 其任法代/董监高/控制企业的风险 | `get_executive_related_risk_scan` |
191
+ | 任职 | 在外任职企业、职务 | `get_executive_positions` |
192
+ | 法代角色 | 担任法代的企业列表 | `get_executive_legal_rep_roles` |
193
+ | 对外投资 | 直接 + 间接持股 | `get_executive_investments` |
194
+ | 控制企业 | 实控企业、投资比例 | `get_executive_controlled_companies` |
195
+ | 关联企业 | 全部关联企业 + 角色 | `get_executive_related_companies` |
196
+ | 个人司法/处罚 | 失信/被执行/限高/限出境/处罚/冻结/出质 | 对应 `get_executive_*`(18 维 + 历史版本) |
197
+ | 历史轨迹 | 历史任职/法代/投资/合伙 | `get_executive_historical_*`(约 20 个) |
198
+
199
+ ### 5.2 招投标域(`mcp__qcc-tender__*`,6 工具)
200
+
201
+ | 补全维度 | 关键字段 | 来源工具 |
202
+ | --- | --- | --- |
203
+ | 企业标讯画像 | 招采/投标/中标/代理数量 | `search_companies` |
204
+ | 企业标讯明细 | 标讯列表 + 角色 | `search_company_tenders` |
205
+ | 招标/中标公告 | 标题、金额、时间 | `search_tenders`(详情 `get_tender_detail`) |
206
+ | 拟建项目 | 项目、投资、阶段 | `search_proposed_projects`(详情 `get_proposed_project_detail`) |
207
+
208
+ ---
209
+
210
+ ## 6. 可清洗补全的通用维度(跨期复用的「列」模型)
211
+
212
+ 无论哪一期,补全输出的列都归入以下**通用维度族**,便于用户勾选与 CSV 回写:
213
+
214
+ 1. **身份维度**:企业名、统一社会信用代码、注册号、曾用名、股票代码/简称。
215
+ 2. **主体维度**:法定代表人、注册资本、成立日期、登记状态、经营状态、注册地址、行业、简介。
216
+ 3. **股权维度**:股东构成、实控人、受益所有人、对外投资、分支机构、历史股东/法人。
217
+ 4. **人员维度**:董监高、主要人员、个人任职/投资/风险。
218
+ 5. **财务维度**:营收、利润、资产负债率、增长率、融资记录、年报。
219
+ 6. **合规风险维度**:经营异常、严重违法、行政处罚、环保处罚、欠税、税收违法、食品/产品/违规通报。
220
+ 7. **司法风险维度**:立案、开庭、裁判文书、失信、被执行、终本、限高、股权冻结/出质、抵押、破产。
221
+ 8. **知产维度**:专利、商标、软著、著作权、标准、数字资产、备案。
222
+ 9. **经营资质维度**:行政许可、资质、纳税资质、信用评价、荣誉、榜单、进出口信用。
223
+ 10. **市场活动维度**:招投标、拟建项目、融资、上市公告、舆情、招聘。
224
+
225
+ ---
226
+
227
+ ## 7. 分期评审与合入规则
228
+
229
+ - 每期交付前须通过 `npm run check`(lint + docs:check + marketing:check + verify-pack + 13 例测试)。
230
+ - 每期新增 Skill 内容须遵守安全不变量:不编造字段、多候选必询问、金额比例计数逐字引用。
231
+ - 历史域(`qcc-history`)与四期人员历史工具需企业认证账号,未授权时 Skill 须显式降级并说明,不得假装补全。
232
+ - 版本号按 SemVer:二期 0.4.0、三期 0.5.0、四期 0.6.0,均需 CHANGELOG + README 版本同步后走 OIDC 发布。
@@ -31,12 +31,30 @@ bash <(curl -fsSL https://raw.githubusercontent.com/duhu2000/dsh-data-cleaning-a
31
31
 
32
32
  ## 3. 能力说明
33
33
 
34
+ ### 3.1 本地清洗 / 补全 / 画像(Skill `data-cleaning`)
35
+
34
36
  | 工具 | 作用 |
35
37
  | --- | --- |
36
38
  | `data_profile` | 输出列概览与金额分布(min/max/sum/count) |
37
39
  | `data_clean_rows` | trim、手机号规范化、剔除缺失必填/负金额/重复行 |
38
40
  | `data_complete_rows` | 空金额填 0、空姓名填占位、报告不可确定性补全的项 |
39
41
 
42
+ ### 3.2 企查查企业名单补全(Skill `enterprise-enrichment`)
43
+
44
+ 先用企查查 MCP 连接插件(`qcc-dsh-mcp-oauth`)完成授权,然后对对话说:
45
+
46
+ > 帮我补全这份企业名单:统一社会信用代码、法人、注册资本、成立日期、登记状态、风险标签。
47
+
48
+ 模型会按 `enterprise-enrichment` Skill 逐个企业调 `mcp__qcc-company__get_company_by_query`
49
+ (消歧,多候选时停下询问)→ `get_company_registration_info`(工商详情)→
50
+ `get_company_risk_scan`(风险标签),最后输出摘要 + Markdown 补全表。
51
+
52
+ **前置条件**:先连接企查查 MCP(未连接时 Skill 会引导执行 `qcc_oauth_connect`)。
53
+
54
+ **本阶段边界**(方案 A,模型中介式):
55
+ - 不重造 OAuth;工具面来自 `qcc-dsh-mcp-oauth`。
56
+ - 逐企业调用,适合中小名单(几十条以内);百级以上大名单的批量补全见路线图(方案 B)。
57
+
40
58
  ## 4. 数据边界
41
59
 
42
60
  - 模型只收到统计摘要(total / kept / dropped / incomplete),**从不读取原始明细行**。
@@ -54,4 +72,6 @@ bash <(curl -fsSL https://raw.githubusercontent.com/duhu2000/dsh-data-cleaning-a
54
72
  - **Q:安装后工具不出现?** A:确认已完全重启 DSH;确认 `dsh plugin list`(或 profile 的
55
73
  `package.json` → `dsh.profile.bundles`)含 `dsh-data-cleaning-agent`。
56
74
  - **Q:XLSX 解析报 `XLSX_UNAVAILABLE`?** A:当前 DSH 组合未安装 `xlsx`;web 组合默认可用。
57
- - **Q:能接企查查补全企业信息吗?** A:路线图见 [PLAN-OSS.md](PLAN-OSS.md)(方案 A 模型中介,后续版本)。
75
+ - **Q:能接企查查补全企业信息吗?** A:可以。先安装并连接 `qcc-dsh-mcp-oauth`,再说"帮我补全这份企业名单",会自动走
76
+ `enterprise-enrichment` Skill(方案 A 模型中介式)。字段契约与二期规划见
77
+ [QCC-ENRICHMENT-DESIGN.md](QCC-ENRICHMENT-DESIGN.md)。
package/lib/index.js CHANGED
@@ -13,6 +13,7 @@
13
13
  import { mountWebRoutes } from './web.js';
14
14
  import { registerTools, TOOL_CLEAN } from './tools.js';
15
15
  import { registerSkill, SKILL_NAME } from './skill.js';
16
+ import { registerEnrichSkill, ENRICH_SKILL_NAME } from './skill-enrich.js';
16
17
 
17
18
  export const name = 'data-cleaning-agent';
18
19
  export const inject = [];
@@ -46,7 +47,9 @@ export function apply(ctx, config) {
46
47
  report.skills = 'present';
47
48
  report.skillRegister = typeof sctx.skills?.register === 'function' ? 'ok' : String(typeof sctx.skills?.register);
48
49
  disposers.push(registerSkill(sctx.skills));
50
+ disposers.push(registerEnrichSkill(sctx.skills));
49
51
  report.skillRegistered = true;
52
+ report.enrichSkillRegistered = true;
50
53
  });
51
54
  } catch (error) {
52
55
  report.skills = `absent: ${error instanceof Error ? error.message : String(error)}`;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * 内嵌 Skill:`enterprise-enrichment`(企查查企业名单补全)。
3
+ *
4
+ * 与 `data-cleaning` 职责分离:
5
+ * - `data-cleaning`:确定性清洗 / 补全 / 概览(本地引擎,不依赖外部数据)。
6
+ * - `enterprise-enrichment`:用企查查 MCP 工具按最新工商信息补全企业名单
7
+ * (依赖 `qcc-dsh-mcp-oauth` 已连接;本 Skill 不重造 OAuth)。
8
+ *
9
+ * 方案 A(模型中介式):模型亲自调用 `mcp__qcc-company__*` / `mcp__qcc-risk__*`
10
+ * 完成消歧 → 工商详情 → 风险标签,再组装结果。本插件零后端改动。
11
+ */
12
+ export const ENRICH_SKILL_NAME = 'enterprise-enrichment';
13
+
14
+ export function registerEnrichSkill(skills) {
15
+ return skills.register({
16
+ name: ENRICH_SKILL_NAME,
17
+ description:
18
+ 'Enrich a list of company names with the latest Qichacha (QCC) business-registration fields via the QCC MCP tools.',
19
+ whenToUse:
20
+ 'When the user gives a list of company names (possibly fuzzy or incomplete) and asks to fill in credit code / legal representative / registered capital / establishment date / registration & business status / risk tags, or asks to "enrich / complete with Qichacha (企查查)".',
21
+ source: 'dsh-data-cleaning-agent',
22
+ content: [
23
+ 'You are an enterprise-list enrichment assistant. You fill a list of company names with the latest Qichacha (QCC) business-registration fields by calling the QCC MCP tools. Never invent, pad, or fabricate any field.',
24
+ '',
25
+ 'Workflow:',
26
+ '1. Check QCC availability first: run `qcc_oauth_status`. If not connected, tell the user to run `qcc_oauth_connect` first and stop. If the token is expired, guide the user to `qcc_oauth_connect` (it reuses the grant and refreshes without a new authorization page).',
27
+ '2. Parse the company-name list from what the user gave (pasted text / CSV / JSON / inline list). Keep only the distinct company-name column.',
28
+ '3. For EACH name: run `mcp__qcc-company__get_company_by_query`.',
29
+ ' - Unique exact match → lock that entity and keep its credit code.',
30
+ ' - Multiple candidates → DO NOT auto-pick the first. List the candidates (name + region + credit code) and ask the user which one to use.',
31
+ ' - No match → mark that row as `unresolved` and continue.',
32
+ '4. For each locked entity: run `mcp__qcc-company__get_company_registration_info` to fill `credit_no` / `legal_rep` / `reg_capital` / `establish_date` / `reg_status` / `biz_status`. When the user also wants risk tags, run `mcp__qcc-risk__get_company_risk_scan` and fill `risk_tags` from the hit dimensions + counts only.',
33
+ '5. Assemble the enriched table. NEVER invent a field — if QCC returns no value, leave it empty and mark the row/field `unresolved`.',
34
+ '6. Report a one-line summary (enriched N / unresolved M / multi-candidate K) plus the enriched table as Markdown. For large lists (dozens of rows or more), process in batches and report progress per batch; do not drop rows silently.',
35
+ '',
36
+ 'Safety rules:',
37
+ '- Never fabricate a credit code, legal representative, capital, amount, ratio, or status.',
38
+ '- Never auto-select among ambiguous candidates — always confirm with the user.',
39
+ '- Quote amounts / ratios / counts exactly as the QCC tool returned them; never recompute or estimate.',
40
+ '- Never expose QCC tokens or credentials.',
41
+ ].join('\n'),
42
+ });
43
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-data-cleaning-agent",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
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",
@@ -21,11 +21,13 @@
21
21
  "marketing",
22
22
  "docs/USER-GUIDE.md",
23
23
  "docs/FIRST-CONTRIBUTION.md",
24
- "docs/COMPATIBILITY.md"
24
+ "docs/COMPATIBILITY.md",
25
+ "docs/QCC-ENRICHMENT-DESIGN.md",
26
+ "docs/QCC-PHASES-ROADMAP.md"
25
27
  ],
26
28
  "scripts": {
27
29
  "test": "node --test",
28
- "lint": "node --check lib/index.js && node --check lib/engine.js && node --check lib/tools.js && node --check lib/skill.js && node --check lib/jobs.js && node --check lib/web.js && node --check lib/client.js",
30
+ "lint": "node --check lib/index.js && node --check lib/engine.js && node --check lib/tools.js && node --check lib/skill.js && node --check lib/skill-enrich.js && node --check lib/jobs.js && node --check lib/web.js && node --check lib/client.js",
29
31
  "docs:check": "node scripts/check-readme-version.mjs",
30
32
  "marketing:check": "node scripts/check-marketing.mjs",
31
33
  "verify-pack": "node scripts/verify-pack.mjs",