lunheng-article-pipeline 18.2.3 → 18.2.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/README.es.md +3 -3
- package/README.hi.md +3 -3
- package/README.md +3 -3
- package/README.pt.md +3 -3
- package/README.zh.md +3 -3
- package/SECURITY.md +5 -2
- package/cordis.patch.yml +27 -7
- package/docs/faq.md +11 -7
- package/docs/introduction.md +2 -2
- package/docs/troubleshooting.md +1 -1
- package/examples/preset/README.md +1 -1
- package/lib/index.js +81 -27
- package/lib/tools.js +6 -2
- package/package.json +1 -1
- package/skills/lunheng-article-pipeline/QUICKSTART.md +2 -2
- package/skills/lunheng-article-pipeline/README.md +1 -1
- package/skills/lunheng-article-pipeline/SKILL.md +3 -3
- package/skills/lunheng-article-pipeline/references/_shared/DSH-/351/233/206/346/210/220/346/226/271/346/241/210.md +1 -1
- package/skills/lunheng-article-pipeline/references/_shared/M-Gate-Algorithm.md +1 -1
- package/skills/lunheng-article-pipeline/references/_shared/audit-checklist-quickref.md +1 -1
- package/skills/lunheng-article-pipeline/references/_shared/degraded-scenarios.md +1 -1
- package/skills/lunheng-article-pipeline/references/_shared/failure-modes.md +1 -1
- package/skills/lunheng-article-pipeline/references/_shared/format-export.md +1 -1
- package/skills/lunheng-article-pipeline/references/_shared//344/270/255/346/226/207/346/225/260/346/215/256/346/272/220/351/233/206/346/210/220.md +1 -1
- package/skills/lunheng-article-pipeline/references/_shared//345/255/227/346/225/260/345/210/244/345/256/232/350/241/250.md +1 -1
- package/skills/lunheng-article-pipeline/references/_shared//346/234/237/345/210/212/345/214/271/351/205/215/347/256/227/346/263/225.md +1 -1
- package/skills/lunheng-article-pipeline/references/_shared//346/234/237/345/210/212/346/225/260/346/215/256/345/272/223.md +1 -1
- package/skills/lunheng-article-pipeline/references/_shared//346/250/241/345/236/213/350/267/257/347/224/261.md +1 -1
- package/skills/lunheng-article-pipeline/references/_shared//350/247/204/350/214/203-/346/234/272/346/242/260/351/227/250/345/257/271/347/205/247/350/241/250.md +7 -3
- package/skills/lunheng-article-pipeline/references/agents/00-/344/270/273/346/216/247-coordinator.md +1 -1
- package/skills/lunheng-article-pipeline/references/agents/00-/344/270/273/346/216/247-/346/211/251/345/261/225/350/201/214/350/264/243.md +1 -1
- package/skills/lunheng-article-pipeline/references/agents/01-/346/226/207/347/214/256/346/243/200/347/264/242-literature-scout.md +1 -1
- package/skills/lunheng-article-pipeline/references/agents/02-/346/225/260/346/215/256/346/243/200/347/264/242-data-scout.md +1 -1
- package/skills/lunheng-article-pipeline/references/agents/03-/346/241/210/344/276/213/346/243/200/347/264/242-case-scout.md +1 -1
- package/skills/lunheng-article-pipeline/references/agents/04-/345/210/206/346/236/220-analyst.md +1 -1
- package/skills/lunheng-article-pipeline/references/agents/05-/345/206/231/344/275/234-writer.md +1 -1
- package/skills/lunheng-article-pipeline/references/agents/06-/346/211/271/345/210/244-critical-companion.md +1 -1
- package/skills/lunheng-article-pipeline/references/agents/07-/345/256/241/350/256/241-auditor.md +1 -1
- package/skills/lunheng-article-pipeline/references/agents/08-/347/273/210/346/243/200-finalizer.md +1 -1
- package/skills/lunheng-article-pipeline/references/agents/09-/345/256/241/347/250/277-peer-reviewer.md +1 -2
- package/skills/lunheng-article-pipeline/references/checkers//344/270/255/346/226/207AI/347/227/225/350/277/271-checker.md +1 -2
- package/skills/lunheng-article-pipeline/references/deliverables.md +1 -1
- package/skills/lunheng-article-pipeline/references/gates/14-/344/270/255/346/226/207AI/347/227/225/350/277/271-gate.md +1 -2
- package/skills/lunheng-article-pipeline/references/glossary.md +1 -1
- package/skills/lunheng-article-pipeline/references/pipeline-readme.md +1 -1
- package/skills/lunheng-article-pipeline/references/templates/AI-/344/275/277/347/224/250/345/243/260/346/230/216-template.md +1 -1
- package/skills/lunheng-article-pipeline/references/templates/G14/346/243/200/346/265/213/346/212/245/345/221/212-template.md +1 -2
- package/skills/lunheng-article-pipeline/references/templates/status-template.md +1 -1
- package/skills/lunheng-article-pipeline/references/templates/style-baseline-template.md +1 -1
- package/skills/lunheng-article-pipeline/references/templates//344/270/273/344/272/272/346/212/225/345/226/202/346/270/205/345/215/225-template.md +1 -1
- package/skills/lunheng-article-pipeline/references/templates//344/270/273/344/272/272/347/241/256/350/256/244-template.md +1 -1
- package/skills/lunheng-article-pipeline/references/templates//344/272/244/344/273/230/350/257/264/346/230/216-template.md +1 -1
- package/skills/lunheng-article-pipeline/references/templates//344/273/273/345/212/241/347/256/200/346/212/245-template.md +1 -1
- package/skills/lunheng-article-pipeline/references/templates//344/277/256/350/256/242/350/257/264/346/230/216-template-full.md +1 -1
- package/skills/lunheng-article-pipeline/references/templates//345/261/200/351/231/220/346/200/247-template.md +1 -1
- package/skills/lunheng-article-pipeline/references/templates//346/212/225/347/250/277/345/260/261/347/273/252/346/243/200/346/237/245/350/241/250-template.md +1 -1
- package/skills/lunheng-article-pipeline/references/templates//346/250/241/345/236/213/350/267/257/347/224/261/350/241/250-template.md +1 -1
- package/skills/lunheng-article-pipeline/references/templates//347/264/240/346/235/220/345/212/240/350/275/275/346/270/205/345/215/225-template.md +1 -1
- package/skills/lunheng-article-pipeline/references/templates//350/277/233/345/261/225-/344/270/273/344/272/272/347/211/210-template.md +1 -1
- package/skills/lunheng-article-pipeline/references/templates//351/227/270/351/227/250/350/256/260/345/275/225-template.md +1 -1
- package/skills/lunheng-article-pipeline/scripts/consistency-check.mjs +32 -1
package/README.es.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Lunheng (lunheng-article-pipeline) — pipeline multiagente para textos largos
|
|
2
2
|
|
|
3
|
-
> 版本:v18.2.
|
|
3
|
+
> 版本:v18.2.4(DSH bundle:package.json + cordis.patch.yml + lib/index.js)
|
|
4
4
|
|
|
5
5
|
> 🌐 [English](README.md) | [中文](README.zh.md) | **Español**(este archivo)| [Português](README.pt.md) | [हिन्दी](README.hi.md)
|
|
6
6
|
|
|
@@ -108,7 +108,7 @@ La capa patch hace dos cosas: **inserta una fila para este paquete** (`- id: lun
|
|
|
108
108
|
Las versiones se publican **solo por tag**; `npm publish` local está prohibido (evita las puertas de CI y la procedencia OIDC, y una versión npm nunca se puede sobrescribir).
|
|
109
109
|
|
|
110
110
|
```sh
|
|
111
|
-
git tag v18.2.
|
|
111
|
+
git tag v18.2.4 && git push origin v18.2.4 # un tag por push (GitHub: >3 tags en un push no dispara workflow)
|
|
112
112
|
# publish.yml ejecuta: puerta 1 consistencia → puerta 2 empaquetado → puerta 3 higiene → puerta 4 humo del paquete → tests
|
|
113
113
|
# → tag/versión iguales → guarda de idempotencia → OIDC publish --provenance --tag dsh → auditoría posterior
|
|
114
114
|
```
|
|
@@ -124,7 +124,7 @@ dsh --profile web --dump-config # muestra una capa "# == lunheng-article-pipel
|
|
|
124
124
|
|
|
125
125
|
Un `dsh` moderno añade la dependencia a `dsh.profile.bundles` en cuanto ve la declaración `dsh.bundle`: instale y reinicie `dsh web`. Solo las instalaciones npm/pnpm puras o las versiones antiguas necesitan la entrada manual.
|
|
126
126
|
|
|
127
|
-
**Como directorio de skill simple** (sin instalación
|
|
127
|
+
**Como directorio de skill simple** (sin instalación; el host vigila la raíz de skills y la refresca al cambiar — el `SKILL.md` del modo uno es una instantánea leída en el `apply` del entry, así que editar el contenido requiere recargar el plugin o abrir una sesión nueva):
|
|
128
128
|
|
|
129
129
|
```sh
|
|
130
130
|
# Copie el DIRECTORIO DE LA SKILL (no la raíz del repositorio) en cualquier raíz de skills:
|
package/README.hi.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# लुन्हेंग (lunheng-article-pipeline) — बहु-एजेंट दीर्घ-लेख पाइपलाइन
|
|
2
2
|
|
|
3
|
-
> 版本:v18.2.
|
|
3
|
+
> 版本:v18.2.4(DSH bundle:package.json + cordis.patch.yml + lib/index.js)
|
|
4
4
|
|
|
5
5
|
> 🌐 [English](README.md) | [中文](README.zh.md) | [Español](README.es.md) | [Português](README.pt.md) | **हिन्दी**(यह फ़ाइल)
|
|
6
6
|
|
|
@@ -108,7 +108,7 @@ patch परत दो काम करती है: **इस पैकेज
|
|
|
108
108
|
संस्करण **केवल tag से** प्रकाशित होते हैं; स्थानीय `npm publish` वर्जित है (यह CI द्वारों और OIDC provenance को दरकिनार करता है, और npm संस्करण कभी अधिलेखित नहीं हो सकता)।
|
|
109
109
|
|
|
110
110
|
```sh
|
|
111
|
-
git tag v18.2.
|
|
111
|
+
git tag v18.2.4 && git push origin v18.2.4 # एक बार में एक ही tag (GitHub: >3 tag एक push में कोई workflow नहीं चलाता)
|
|
112
112
|
# publish.yml क्रम: द्वार 1 सुसंगति → द्वार 2 पैकेजिंग → द्वार 3 स्वच्छता → द्वार 4 पैकेज स्मोक → स्क्रिप्ट परीक्षण
|
|
113
113
|
# → tag/संस्करण समानता → idempotency गार्ड → OIDC publish --provenance --tag dsh → प्रकाशन-पश्चात लेखा-परीक्षा
|
|
114
114
|
```
|
|
@@ -124,7 +124,7 @@ dsh --profile web --dump-config # "# == lunheng-article-pipeline" परत
|
|
|
124
124
|
|
|
125
125
|
नया `dsh` `dsh.bundle` घोषणा देखते ही निर्भरता को `dsh.profile.bundles` में जोड़ देता है — स्थापित करें और `dsh web` पुनः आरंभ करें। केवल शुद्ध npm/pnpm स्थापना या पुराने संस्करणों में मैनुअल प्रविष्टि चाहिए।
|
|
126
126
|
|
|
127
|
-
**सादे स्किल निर्देशिका के रूप में** (स्थापना
|
|
127
|
+
**सादे स्किल निर्देशिका के रूप में** (स्थापना नहीं; होस्ट स्किल-मूल की निगरानी करता है और बदलाव पर तुरंत ताज़ा करता है — मोड एक का `SKILL.md` entry के `apply` समय पढ़ा गया स्नैपशॉट है, इसलिए सामग्री बदलने पर प्लगइन पुनःलोड या नया सत्र आवश्यक है):
|
|
128
128
|
|
|
129
129
|
```sh
|
|
130
130
|
# स्किल निर्देशिका (रिपॉज़िटरी रूट नहीं) को किसी भी DSH स्किल-मूल में प्रतिलिपि करें:
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> 🌐 **English** (this file) | [中文](README.zh.md) | [Español](README.es.md) | [Português](README.pt.md) | [हिन्दी](README.hi.md)
|
|
4
4
|
|
|
5
|
-
> 版本:v18.2.
|
|
5
|
+
> 版本:v18.2.4(DSH bundle:package.json + cordis.patch.yml + lib/index.js)
|
|
6
6
|
|
|
7
7
|
> A DeepSeek Harness (DSH) bundle that registers one on-demand agent skill. The skill turns long-form production — academic papers, industry analysis, business commentary, and long-form articles — into a **9-role pipeline with a human in the loop**.
|
|
8
8
|
|
|
@@ -108,7 +108,7 @@ The patch layer does two things: it **inserts one row for this package** (`- id:
|
|
|
108
108
|
Releases are **tag-only**; a local `npm publish` is forbidden (it would bypass the CI gates and OIDC provenance, and a published npm version can never be overwritten).
|
|
109
109
|
|
|
110
110
|
```sh
|
|
111
|
-
git tag v18.2.
|
|
111
|
+
git tag v18.2.4 && git push origin v18.2.4 # push one tag at a time (GitHub: >3 tags in one push triggers no workflow)
|
|
112
112
|
# publish.yml then runs gate 1 consistency → gate 2 packaging surface → gate 3 hygiene → gate 4 pack smoke → script tests
|
|
113
113
|
# → tag/version equality → idempotency guard → OIDC publish --provenance --tag dsh → post-publish audit
|
|
114
114
|
```
|
|
@@ -124,7 +124,7 @@ dsh --profile web --dump-config # shows the "# == lunheng-article-pipeline" la
|
|
|
124
124
|
|
|
125
125
|
A modern `dsh` adds the dependency to `dsh.profile.bundles` automatically once it sees the `dsh.bundle` declaration — install and restart `dsh web`. Only plain npm/pnpm installs or older builds need the manual `dsh.profile.bundles` entry.
|
|
126
126
|
|
|
127
|
-
**As a plain skill directory** (no install,
|
|
127
|
+
**As a plain skill directory** (no install; the host watches the skill root and refreshes it on change — mode one's `SKILL.md` is a snapshot read at entry `apply` time, so content edits need a plugin reload or a new session):
|
|
128
128
|
|
|
129
129
|
```sh
|
|
130
130
|
# Copy the SKILL directory (not the repository root) into any DSH skill root:
|
package/README.pt.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Lunheng (lunheng-article-pipeline) — pipeline multiagente para textos longos
|
|
2
2
|
|
|
3
|
-
> 版本:v18.2.
|
|
3
|
+
> 版本:v18.2.4(DSH bundle:package.json + cordis.patch.yml + lib/index.js)
|
|
4
4
|
|
|
5
5
|
> 🌐 [English](README.md) | [中文](README.zh.md) | [Español](README.es.md) | **Português**(este arquivo)| [हिन्दी](README.hi.md)
|
|
6
6
|
|
|
@@ -108,7 +108,7 @@ A camada patch faz duas coisas: **insere uma linha para este pacote** (`- id: lu
|
|
|
108
108
|
As versões são publicadas **apenas por tag**; `npm publish` local é proibido (contorna os portões de CI e a proveniência OIDC, e uma versão npm nunca pode ser sobrescrita).
|
|
109
109
|
|
|
110
110
|
```sh
|
|
111
|
-
git tag v18.2.
|
|
111
|
+
git tag v18.2.4 && git push origin v18.2.4 # uma tag por push (GitHub: >3 tags em um push não dispara workflow)
|
|
112
112
|
# publish.yml executa: portão 1 consistência → portão 2 empacotamento → portão 3 higiene → portão 4 teste de fumaça do pacote → testes
|
|
113
113
|
# → tag/versão iguais → guarda de idempotência → OIDC publish --provenance --tag dsh → auditoria posterior
|
|
114
114
|
```
|
|
@@ -124,7 +124,7 @@ dsh --profile web --dump-config # mostra uma camada "# == lunheng-article-pipe
|
|
|
124
124
|
|
|
125
125
|
Um `dsh` moderno adiciona a dependência a `dsh.profile.bundles` assim que vê a declaração `dsh.bundle`: instale e reinicie o `dsh web`. Somente instalações npm/pnpm puras ou versões antigas precisam da entrada manual.
|
|
126
126
|
|
|
127
|
-
**Como diretório de skill simples** (sem instalação
|
|
127
|
+
**Como diretório de skill simples** (sem instalação; o host vigia a raiz de skills e a atualiza a cada mudança — o `SKILL.md` do modo um é um instantâneo lido no `apply` do entry, então editar o conteúdo exige recarregar o plugin ou abrir uma sessão nova):
|
|
128
128
|
|
|
129
129
|
```sh
|
|
130
130
|
# Copie o DIRETÓRIO DA SKILL (não a raiz do repositório) para qualquer raiz de skills:
|
package/README.zh.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> 🌐 [English](README.md) | **中文**(本文件)| [Español](README.es.md) | [Português](README.pt.md) | [हिन्दी](README.hi.md)
|
|
4
4
|
|
|
5
|
-
> 版本:v18.2.
|
|
5
|
+
> 版本:v18.2.4(DSH bundle:package.json + cordis.patch.yml + lib/index.js)
|
|
6
6
|
|
|
7
7
|
> 一个 DeepSeek Harness(DSH)bundle 插件,注册一个按需加载的 agent 技能。它把深度长文的生产——学术论文、行业分析、商业评论、公众号深文——变成**带人在环节点的 9 角色流水线**。
|
|
8
8
|
|
|
@@ -108,7 +108,7 @@ patch 层做两件事:**插入一行本包自注册行**(`- id: lunheng-arti
|
|
|
108
108
|
**只推 tag 发布,禁止本地 `npm publish`**(本地直发会绕过 CI 三道门与 OIDC 来源证明,且 npm 版本不可覆盖)。
|
|
109
109
|
|
|
110
110
|
```sh
|
|
111
|
-
git tag v18.2.
|
|
111
|
+
git tag v18.2.4 && git push origin v18.2.4 # 一次只推 1 个 tag(GitHub:单次 push >3 个 tag 不触发任何 workflow)
|
|
112
112
|
# publish.yml 依次跑:门 1 一致性 → 门 2 打包面 → 门 3 机械卫生 → 门 4 打包产物冒烟 → 脚本回归测试
|
|
113
113
|
# → tag/版本一致校验 → 幂等守卫 → OIDC 发布 --provenance --tag dsh → 发布后审计
|
|
114
114
|
```
|
|
@@ -124,7 +124,7 @@ dsh --profile web --dump-config # 应出现 "# == lunheng-article-pipeline"
|
|
|
124
124
|
|
|
125
125
|
新版 dsh 看到 `dsh.bundle` 声明后会自动把依赖加进 `dsh.profile.bundles`——装完重启 `dsh web` 即可。仅当用纯 npm/pnpm 安装或旧版 dsh 时,才需手工在 profile 的 `package.json` 里加 `dsh.profile.bundles` 条目。
|
|
126
126
|
|
|
127
|
-
|
|
127
|
+
**方式二:作为纯技能目录**(免安装;宿主监听技能根、文件改动即刷新目录——方式一的 `SKILL.md` 是入口 `apply` 期读的快照,改内容需重载插件或重开会话)
|
|
128
128
|
|
|
129
129
|
```sh
|
|
130
130
|
# 复制**技能目录**(不是仓库根)到任一 DSH 技能根:
|
package/SECURITY.md
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
# 安全策略(SECURITY)
|
|
2
2
|
|
|
3
|
-
> 版本:v18.2.
|
|
3
|
+
> 版本:v18.2.4(DSH 原生插件,发布于 2026-09-13)
|
|
4
4
|
|
|
5
5
|
## 上报漏洞
|
|
6
6
|
|
|
7
7
|
发现安全问题时**请勿开公开 issue**。请通过以下任一私密渠道上报:
|
|
8
8
|
|
|
9
|
-
- GitHub **Private vulnerability reporting
|
|
9
|
+
- GitHub **Private vulnerability reporting**(推荐):<https://github.com/zuoyunlai/lunheng-article-pipeline-dsh/security/advisories/new>
|
|
10
|
+
> **v18.2.4 复核(第三方审计 D.2)**:该开关此前**没开**——`GET /repos/…/private-vulnerability-reporting` 返回 `{"enabled":false}`,即本节旧文写的「仓库 → Security → Report a vulnerability」**当时是个死链**(公开仓库上尤其糟:报告者照文档走却找不到入口,只剩开公开 issue 一途)。现已开启并核验为 `{"enabled":true}`。
|
|
10
11
|
- 邮件:`zuoyunlai@outlook.com`(标题加 `[SECURITY] lunheng-article-pipeline`)
|
|
11
12
|
|
|
12
13
|
请在报告中给出:受影响版本(`package.json` 的 `version`)、复现步骤、影响面判断、以及你期望的披露时限。
|
|
@@ -32,6 +33,8 @@
|
|
|
32
33
|
- **幂等守卫**:目标版本已存在于 npm 时跳过发布。
|
|
33
34
|
- **发布后审计**:断言 `npm view <pkg>@<ver> gitHead` == 本次提交 SHA,且 `dist-tags.dsh` 指向该版本。
|
|
34
35
|
- 历史版本 `2.5.2-dsh.8`–`.12` 为**本地手工发布、无 provenance**(已在 `CHANGELOG.md` 记录);自 `2.5.2-dsh.13` 起恢复 tag + OIDC 流程。
|
|
36
|
+
- **`NPM_TOKEN` 的用途与治理(v18.2.4 增补,第三方审计 G.1)**:发布本身走 OIDC、**不需要** token;该 secret **只**用于发布后 `npm dist-tag add … latest` 这一步——OIDC 覆盖的是 `npm publish`,而 `npm dist-tag` 仍需写鉴权(工作流注释已记实测:无 token 时该命令因无鉴权 exit 1;故工作流写成「无 token 只告警、不失败」,latest 由维护者手工补打)。
|
|
37
|
+
> **治理要求**:① 用**细粒度 token**、只授本包写权限、设最短有效期;② 定期轮换;③ **一旦出现在聊天记录 / 日志 / 截图 / CI 输出中即视为已泄露**,立即 revoke 并重发;④ 该 token 永远不得打印(`publish.yml` 只经 `env:` 传递,不 `echo`)。
|
|
35
38
|
|
|
36
39
|
## 支持的版本
|
|
37
40
|
|
package/cordis.patch.yml
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# lunheng-article-pipeline bundle patch(DSH 原生插件 v18.2.
|
|
1
|
+
# lunheng-article-pipeline bundle patch(DSH 原生插件 v18.2.4)
|
|
2
2
|
#
|
|
3
3
|
# 本文件用 DSH cordis-plugin-include 的 `- insert:` 列表语法在 standard 组合树之上叠加 4 行:
|
|
4
4
|
# 1. **本包入口(自注册行)**:`name: lunheng-article-pipeline` → loader 按包名解析到
|
|
@@ -56,14 +56,34 @@
|
|
|
56
56
|
name: '@deepseek-ai/dsh-tool-subagent'
|
|
57
57
|
# v18.0.5(第三方审计 P2-12):`LUNHENG_TIERING=off` 此前只让 agentOptions 变 undefined,
|
|
58
58
|
# **三行仍挂在组合树里**(实测每个会话的工具数恒为 29)——用户以为关了,其实只是"不分档但仍多 3 个工具"。
|
|
59
|
-
#
|
|
60
|
-
#
|
|
61
|
-
#
|
|
62
|
-
#
|
|
63
|
-
#
|
|
64
|
-
#
|
|
59
|
+
# 官方支持**行级**门控,故加这一行。
|
|
60
|
+
# ✅ **v18.2.4 已由宿主源码证实**(此前 v18.0.5 只能标注「未验证」——因 `--dump-config` 只打印
|
|
61
|
+
# 声明行,判定实验「改成恒真后 dump 里三行依旧在」证明的是 dump 不反映裁剪,不是键无效):
|
|
62
|
+
# · `disabled` 是 loader 的**一等选项**:`@deepseek-ai/cordis-plugin-loader` 的
|
|
63
|
+
# `src/config/entry.ts:19` 声明 `disabled?: boolean | null`;
|
|
64
|
+
# · `disabledOf()`(同文件 :104-107)对 `!!js` 形求值——
|
|
65
|
+
# `isJsExpr(options.disabled) ? Boolean(this.evaluate(options.disabled.__jsExpr)) : Boolean(options.disabled)`,
|
|
66
|
+
# 即「表达式求值为假 = 该行禁用」,判定只取决于表达式取值本身;
|
|
67
|
+
# · `refresh()`(:124-128)首行即 `if (this.disabled) return` → **不进 init,行不装载**;
|
|
68
|
+
# · `update()`(:181-189)在 `_disabled(candidate)` 为真时 `_dispose(previous)` → 热更新该键
|
|
69
|
+
# 会**主动卸载**已装载的 fiber(不是只对新会话生效)。
|
|
70
|
+
# 宿主自用先例(同键同形):DSH Desktop 随包的 `cordis.patch.yml`
|
|
71
|
+
# —— `disabled: !!js process.platform === 'linux'`。
|
|
72
|
+
# ⚠️ **残留不确定(如实保留)**:以上证明的是「loader 按该键裁剪行」;**本机 `--dump-config` 仍只
|
|
73
|
+
# 打印声明行**,且 DSH Desktop 的 dsh shim 硬编码 DSH_HOME、无法用干净 profile 实测组合树,
|
|
74
|
+
# 故「off 时工具数是否真的少 3」仍需在能起 headless 的环境核对真实工具清单。
|
|
75
|
+
# 退化行为安全:即便某版本忽略该键,行为与 v18.0.4 一致(三行仍在、模型继承)——不产生错误语义。
|
|
65
76
|
disabled: !!js "process.env.LUNHENG_TIERING === 'off'"
|
|
66
77
|
config:
|
|
78
|
+
# ✅ v18.2.4:`provider: spawn` 的**合法性已证实**(v18.0.5 起列为「待问 DSH 官方」的开放问题,现已结案):
|
|
79
|
+
# ① 官方 `config-catalog`(生成自 `packages/subagent/tool-subagent/src/index.ts:48`)的
|
|
80
|
+
# `@deepseek-ai/dsh-tool-subagent` Config 注释原文即「The `ctx.subagents` provider name
|
|
81
|
+
# to start runs on (e.g. `spawn`, `acp`)」——`spawn` 是被点名的合法取值;
|
|
82
|
+
# ② 该名来自 `@deepseek-ai/dsh-subagent-spawn-in-process`:注册名默认 `spawn`
|
|
83
|
+
# (`Config = z.object({ providerName: z.string().default('spawn') })`,其 lib/index.js:13 + :42);
|
|
84
|
+
# ③ 本包同时用的 `backgroundMode: continuable` **要求** provider 具备 `prepareContinuable` 能力
|
|
85
|
+
# (官方 `subsystems/subagent.zh.md`:缺该方法的 provider 上发起可继续 start 会被拒),
|
|
86
|
+
# 而该 provider **确有** `prepareContinuable()`(其 lib/index.js:37)→ 能力配对成立。
|
|
67
87
|
provider: spawn
|
|
68
88
|
toolName: subagent_retrieval
|
|
69
89
|
backgroundMode: continuable
|
package/docs/faq.md
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# FAQ
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 为什么第三方插件市场(如 dshmarket)里显示「安装完成但校验失败 / 入口产物缺失」?
|
|
4
4
|
|
|
5
|
-
> **v18.0.0 起已不适用**:本包现在带 JS 包入口(`main` → `lib/index.js`,注册技能并经 `ctx.effect`
|
|
5
|
+
> **v18.0.0 起已不适用**:本包现在带 JS 包入口(`main` → `lib/index.js`,注册技能并经 `ctx.effect` 可逆注册),「只认 JS 入口」一类校验器不再误报。若仍看到该校验失败,请确认安装的是 v18.0.0 及以上。
|
|
6
|
+
>
|
|
7
|
+
> **先分清归属(v18.2.4 补注)**:`dshmarket` 与各类插件市场都是**第三方社区项目**,不是 DSH 官方组件,也不在本包的依赖或支持范围内——本包只依赖 DSH 宿主本身(且 `@deepseek-ai/dsh` 是 optional peer)。故「市场里的显示」与「本包能否装载」是两件事:前者出问题找市场,后者出问题看本文件与 [`troubleshooting.md`](troubleshooting.md)。
|
|
6
8
|
|
|
7
9
|
## 本包「零可执行内容」吗?
|
|
8
10
|
|
|
@@ -14,16 +16,18 @@
|
|
|
14
16
|
|
|
15
17
|
实测技能可正常加载:`dsh --profile <profile> --dump-config` 可见本包层与三档 `tool-subagent-*` 行,新会话的技能目录能列出 `lunheng-article-pipeline`。
|
|
16
18
|
|
|
17
|
-
##
|
|
19
|
+
## 版本号为什么是纯语义化三段式?
|
|
18
20
|
|
|
19
21
|
DSH 版独立维护、独立版本线,版本号不与任何外部版本线共享。**v17.0.0 起版本号 = 纯语义化版本,迭代号进 major**:
|
|
20
22
|
|
|
21
23
|
| 场景 | 版本 |
|
|
22
24
|
|---|---|
|
|
23
|
-
| 本轮迭代 |
|
|
24
|
-
| 上一轮迭代(未单独发布,内容随本版首发) |
|
|
25
|
-
| 同一轮内修补 |
|
|
26
|
-
| 同一轮内小步改进 |
|
|
25
|
+
| 本轮迭代 | 抬 minor(`18.2.0` 形态) |
|
|
26
|
+
| 上一轮迭代(未单独发布,内容随本版首发) | 抬 major(`17.0.0` 形态) |
|
|
27
|
+
| 同一轮内修补 | 抬 patch(`18.2.4` 形态) |
|
|
28
|
+
| 同一轮内小步改进 | 抬 patch(同上) |
|
|
29
|
+
|
|
30
|
+
> **表中数字只是示例**(v18.2.4 更正):旧版此处写死成当时的版本 `18.2.1`,此后每次 bump 都不同步、静默滞留了三个版本——**「当前版本」的唯一真源是 `package.json` 的 `version`**(也可 `npm view lunheng-article-pipeline version`)。本文件刻意不再复述具体当前版本号。
|
|
27
31
|
|
|
28
32
|
**为什么不能写成 `dsh.17.0`**:npm 强制 [semver](https://semver.org),`major.minor.patch` 三段必须是数字,`dsh` 只能出现在 `-`(prerelease)或 `+`(build metadata)之后——实测 `npm publish` 会直接以 `Invalid version` 拒绝。
|
|
29
33
|
|
package/docs/introduction.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> **论衡(lunheng-article-pipeline)** 是一个多 Agent 深度长文生产流水线,DeepSeek Harness(dsh)bundle 插件。它不是让一个 AI 直接写文章,而是让一支 **9 个 AI 角色组成的"论文生产小队"** 按既定协议协作:定题 → 三线并行检索 → 分析 → 写作 → 批判 → 审计 → 审稿 → 终检。每一步都有明确产出物、交接报告与质量闸门,最终交付**有证据底座、有反方论证、有独立审计、有人工核验节点**的文章。
|
|
4
4
|
|
|
5
|
-
> 适用:公众号深度长文、研究报告、学术论文、商业评论、行业分析——任何"要站得住脚"的长内容。当前版本 **v18.2.
|
|
5
|
+
> 适用:公众号深度长文、研究报告、学术论文、商业评论、行业分析——任何"要站得住脚"的长内容。当前版本 **v18.2.4**(DSH 独立版本)。
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -170,7 +170,7 @@ dsh plugin --profile web add lunheng-article-pipeline
|
|
|
170
170
|
## 获取方式
|
|
171
171
|
|
|
172
172
|
- **GitHub(DSH bundle)**:https://github.com/zuoyunlai/lunheng-article-pipeline-dsh
|
|
173
|
-
- **npm**:`lunheng-article-pipeline@dsh`(dist-tag `dsh` = 最新 DSH 迭代版);锁定具体版本可写 `@18.2.
|
|
173
|
+
- **npm**:`lunheng-article-pipeline@dsh`(dist-tag `dsh` = 最新 DSH 迭代版);锁定具体版本可写 `@18.2.4`
|
|
174
174
|
- **历史版本线(独立化前)**:https://github.com/zuoyunlai/lunheng-article-pipeline
|
|
175
175
|
|
|
176
176
|
---
|
package/docs/troubleshooting.md
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
```sh
|
|
13
13
|
# 1. 在 profile 里声明 bundle 依赖(DSH 读 dsh.bundle.patch 找到 cordis.patch.yml 加载)
|
|
14
14
|
dsh plugin --profile web add lunheng-article-pipeline@dsh # 推荐:跟随最新 DSH 迭代版
|
|
15
|
-
# 锁定具体版本:dsh plugin --profile web add lunheng-article-pipeline@18.2.
|
|
15
|
+
# 锁定具体版本:dsh plugin --profile web add lunheng-article-pipeline@18.2.4
|
|
16
16
|
|
|
17
17
|
# 2. (可选)设三档 subagent 工具的 provider/model 环境变量
|
|
18
18
|
# 不设任何变量 = 三档全部继承会话模型(安全默认,单模型用户无需本步)
|
package/lib/index.js
CHANGED
|
@@ -35,15 +35,24 @@ const skillDir = join(packageRoot, 'skills', 'lunheng-article-pipeline')
|
|
|
35
35
|
* Split the YAML frontmatter block from SKILL.md into routing fields and body.
|
|
36
36
|
* A malformed or missing block falls back to the full text as the body and an
|
|
37
37
|
* empty field map, so the registration still succeeds with its fallback copy.
|
|
38
|
+
*
|
|
39
|
+
* v18.2.4(审计 C.1):行尾与 BOM 归一后再解析。此前用 `text.startsWith('---\n')`
|
|
40
|
+
* 判定,而 `readFileSync(p, 'utf8')` **不做行尾归一**——SKILL.md 一旦是 CRLF 行尾
|
|
41
|
+
* (Windows `core.autocrlf=true` 检出、或编辑器另存为 CRLF),首行是 `---\r\n`,
|
|
42
|
+
* 判定为假 → frontmatter 整块**静默**退化成内置兜底描述,而 description/whenToUse
|
|
43
|
+
* 恰是模型侧路由的唯一依据(`whenToUse` 丢失后连注册字段都会消失),静态门全绿也照样漏过。
|
|
38
44
|
* @param text - raw SKILL.md content.
|
|
39
|
-
* @returns parsed routing fields (present keys only)
|
|
45
|
+
* @returns parsed routing fields (present keys only), the instruction body, and
|
|
46
|
+
* whether the frontmatter block was actually recognized.
|
|
40
47
|
*/
|
|
41
48
|
function splitFrontmatter(text) {
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
-
|
|
49
|
+
// 行尾归一(CRLF / 孤立 CR → LF)+ 去 BOM:两者都只影响解析,不影响正文语义。
|
|
50
|
+
const norm = text.replace(/^\uFEFF/, '').replace(/\r\n?/g, '\n')
|
|
51
|
+
// 首行必须是 `---`,且必须有**成行**的闭合 `---`(缺闭合 = 未解析,不猜)。
|
|
52
|
+
const match = /^---[ \t]*\n([\s\S]*?)\n---[ \t]*(?:\n|$)/.exec(norm)
|
|
53
|
+
if (!match) return { fields: {}, body: norm, parsed: false }
|
|
54
|
+
const meta = match[1]
|
|
55
|
+
const body = norm.slice(match[0].length).replace(/^\n+/, '')
|
|
47
56
|
const read = (key) => {
|
|
48
57
|
const match = new RegExp(`^${key}:\\s*(.+)$`, 'm').exec(meta)
|
|
49
58
|
return match?.[1]?.trim().replace(/^["']|["']$/g, '')
|
|
@@ -51,29 +60,73 @@ function splitFrontmatter(text) {
|
|
|
51
60
|
return {
|
|
52
61
|
fields: { description: read('description'), whenToUse: read('whenToUse') },
|
|
53
62
|
body,
|
|
63
|
+
parsed: true,
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Build the entry's status reporter (v18.2.4,审计 C.3).
|
|
69
|
+
*
|
|
70
|
+
* 宿主带 Cordis `logger` 时走正规日志面,否则退回 `console.error`。此前 3 条
|
|
71
|
+
* 「已注册 / 已启用」状态行**无条件**写 stderr,宿主每次启动都刷屏,而这些信息本就
|
|
72
|
+
* 只对宿主日志有用。口径:`info`(成功)可被 `LUNHENG_QUIET=1` 静音;`warn`(降级 / 失败)
|
|
73
|
+
* **不静音**——「静默降级」正是 v18.0.0 事故的形态,必须始终可见。
|
|
74
|
+
* @param ctx - the plugin context (minimal hosts may carry no logger).
|
|
75
|
+
* @returns a `(level, message) => void` reporter bound to this context.
|
|
76
|
+
*/
|
|
77
|
+
function makeReporter(ctx) {
|
|
78
|
+
const logger = ctx?.logger
|
|
79
|
+
const quiet = process.env.LUNHENG_QUIET === '1' || process.env.LUNHENG_QUIET === 'true'
|
|
80
|
+
return (level, message) => {
|
|
81
|
+
if (level === 'info' && quiet) return
|
|
82
|
+
if (logger && typeof logger[level] === 'function') logger[level](message)
|
|
83
|
+
else console.error(message) // 宿主无日志面时不丢信息(宁可见勿静默)
|
|
54
84
|
}
|
|
55
85
|
}
|
|
56
86
|
|
|
57
87
|
/**
|
|
58
88
|
* Register the pipeline skill. Registration is an effect: the disposer
|
|
59
89
|
* returned by `ctx.skills.register()` removes the contribution on unload.
|
|
60
|
-
* @param ctx - Cordis context
|
|
90
|
+
* @param ctx - Cordis context; the injected `skills` service is the hard
|
|
91
|
+
* dependency (its absence is a host-contract violation: it is reported and
|
|
92
|
+
* skipped, never a TypeError), while the C-group services stay optional.
|
|
61
93
|
*/
|
|
62
94
|
export function apply(ctx) {
|
|
95
|
+
const say = makeReporter(ctx)
|
|
63
96
|
const skillPath = join(skillDir, 'SKILL.md')
|
|
64
|
-
const { fields, body } = splitFrontmatter(readFileSync(skillPath, 'utf8'))
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
)
|
|
97
|
+
const { fields, body, parsed } = splitFrontmatter(readFileSync(skillPath, 'utf8'))
|
|
98
|
+
// 审计 C.2:解析失败此前**静默**退回兜底 description——模型侧路由字段丢了却没有任何信号。
|
|
99
|
+
if (!parsed) {
|
|
100
|
+
say(
|
|
101
|
+
'warn',
|
|
102
|
+
`· 论衡技能 frontmatter 未解析(SKILL.md 首行不是成行 \`---\` 或缺闭合行):${skillPath}` +
|
|
103
|
+
' —— 已退回内置兜底 description,whenToUse 未注册;请检查该文件是否被 CRLF / 前置空行 / BOM 破坏。',
|
|
104
|
+
)
|
|
105
|
+
}
|
|
106
|
+
// 审计 E.2(v18.2.4):`skills` 是 `inject` 声明的**硬依赖**——合规宿主在 apply 前就已就绪,
|
|
107
|
+
// 故这条不是「降级」分支而是「宿主违约」分支:响亮点名后**跳过注册**,但 C 组可选能力照常安装
|
|
108
|
+
// (入口不因缺一个服务就整体崩掉)。此前缺失时抛的是
|
|
109
|
+
// `Cannot read properties of undefined (reading 'register')`——一句话能说清的事不该以 TypeError 出现。
|
|
110
|
+
if (ctx?.skills?.register) {
|
|
111
|
+
ctx.effect(() =>
|
|
112
|
+
ctx.skills.register({
|
|
113
|
+
name: 'lunheng-article-pipeline',
|
|
114
|
+
source: 'bundled',
|
|
115
|
+
description:
|
|
116
|
+
fields.description ??
|
|
117
|
+
'论衡:多 Agent 深度长文流水线(学术论文 / 商业评论 / 行业分析 / 公众号)。',
|
|
118
|
+
...(fields.whenToUse ? { whenToUse: fields.whenToUse } : {}),
|
|
119
|
+
content: body,
|
|
120
|
+
resourceBase: { kind: 'directory', path: skillDir },
|
|
121
|
+
}),
|
|
122
|
+
)
|
|
123
|
+
} else {
|
|
124
|
+
say(
|
|
125
|
+
'warn',
|
|
126
|
+
'· 论衡技能未注册:宿主 ctx 缺 `skills` 服务(inject 声明的硬依赖未满足)——' +
|
|
127
|
+
'原生工具 / 机制写保护 / 人类命令仍会尝试安装。',
|
|
128
|
+
)
|
|
129
|
+
}
|
|
77
130
|
|
|
78
131
|
// ── C 组(v18.1.0):原生工具 / 机制写保护 / 人类命令 ──────────────────────
|
|
79
132
|
// 设计要点(官方依据见各模块头注释):
|
|
@@ -88,12 +141,12 @@ export function apply(ctx) {
|
|
|
88
141
|
;(async () => {
|
|
89
142
|
try {
|
|
90
143
|
const { installLunhengTools } = await import('./tools.js')
|
|
91
|
-
const d = await installLunhengTools(ctx, { skillRoot: skillDir })
|
|
144
|
+
const d = await installLunhengTools(ctx, { skillRoot: skillDir, report: say })
|
|
92
145
|
if (!alive) { for (const x of d) try { x?.() } catch { /* 已卸载 */ } return }
|
|
93
146
|
disposers.push(...d)
|
|
94
|
-
if (d.length)
|
|
147
|
+
if (d.length) say('info', `· 论衡原生工具已注册:${d.length} 个(lunheng_m_gate / lunheng_char_count,均只读)`)
|
|
95
148
|
} catch (e) {
|
|
96
|
-
|
|
149
|
+
say('warn', `· 论衡原生工具安装失败(不影响技能与流水线):${String(e?.message || e).slice(0, 120)}`)
|
|
97
150
|
}
|
|
98
151
|
try {
|
|
99
152
|
const { installMechanismGuard } = await import('./guard.js')
|
|
@@ -107,12 +160,13 @@ export function apply(ctx) {
|
|
|
107
160
|
if (!alive) { try { d?.() } catch { /* 已卸载 */ } return }
|
|
108
161
|
if (d) {
|
|
109
162
|
disposers.push(d)
|
|
110
|
-
|
|
163
|
+
say(
|
|
164
|
+
'info',
|
|
111
165
|
'· 论衡机制文件写保护已启用(write/edit 类工具对技能包内路径一律否决;主人授权时设 LUNHENG_ALLOW_MECH_EDIT=1)',
|
|
112
166
|
)
|
|
113
167
|
}
|
|
114
168
|
} catch (e) {
|
|
115
|
-
|
|
169
|
+
say('warn', `· 论衡机制写保护安装失败(不影响技能):${String(e?.message || e).slice(0, 120)}`)
|
|
116
170
|
}
|
|
117
171
|
try {
|
|
118
172
|
const { installStatusCommand } = await import('./commands.js')
|
|
@@ -120,10 +174,10 @@ export function apply(ctx) {
|
|
|
120
174
|
if (!alive) { try { d?.() } catch { /* 已卸载 */ } return }
|
|
121
175
|
if (d) {
|
|
122
176
|
disposers.push(d)
|
|
123
|
-
|
|
177
|
+
say('info', '· 论衡人类命令已注册:/lunheng-status(不产生模型消息)')
|
|
124
178
|
}
|
|
125
179
|
} catch (e) {
|
|
126
|
-
|
|
180
|
+
say('warn', `· 论衡人类命令安装失败(不影响技能):${String(e?.message || e).slice(0, 120)}`)
|
|
127
181
|
}
|
|
128
182
|
})()
|
|
129
183
|
return () => {
|
package/lib/tools.js
CHANGED
|
@@ -54,8 +54,12 @@ const clip = (s, n = 500) => String(s ?? '').slice(0, n)
|
|
|
54
54
|
* @param opts.defineToolFactory - 可选:自定义 `defineTool` 来源(默认 `() => import('@deepseek-ai/dsh-tools')`)。
|
|
55
55
|
* 存在的意义:① 测试环境(裸仓库 / CI)没有宿主包,可注入契约等价的替身,从而**照常覆盖工具行为**;
|
|
56
56
|
* ② 宿主换包名时只改这一处。
|
|
57
|
+
* @param opts.report - 可选:状态输出回调 `(level, message) => void`(默认 `console.error`)。
|
|
58
|
+
* v18.2.4(审计 C.3):宿主有 Cordis `logger` 时入口会传入按 logger 分流的 reporter,
|
|
59
|
+
* 避免每次启动无条件刷 stderr。
|
|
57
60
|
*/
|
|
58
|
-
export async function installLunhengTools(ctx, { skillRoot, defineToolFactory } = {}) {
|
|
61
|
+
export async function installLunhengTools(ctx, { skillRoot, defineToolFactory, report } = {}) {
|
|
62
|
+
const say = typeof report === 'function' ? report : (level, message) => console.error(message)
|
|
59
63
|
const tools = ctx.get('tools')
|
|
60
64
|
if (!tools?.register) return []
|
|
61
65
|
let defineTool
|
|
@@ -64,7 +68,7 @@ export async function installLunhengTools(ctx, { skillRoot, defineToolFactory }
|
|
|
64
68
|
;({ defineTool } = await factory())
|
|
65
69
|
if (typeof defineTool !== 'function') throw new Error('defineTool 不是函数')
|
|
66
70
|
} catch (e) {
|
|
67
|
-
|
|
71
|
+
say('warn', `· 论衡原生工具未启用(无法取得 defineTool:${String(e?.code || e?.message).slice(0, 80)})——技能与流水线不受影响,仍可用 pwsh 调脚本`)
|
|
68
72
|
return []
|
|
69
73
|
}
|
|
70
74
|
const disposers = []
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lunheng-article-pipeline",
|
|
3
|
-
"version": "18.2.
|
|
3
|
+
"version": "18.2.4",
|
|
4
4
|
"description": "论衡(lunheng-article-pipeline)— 多 Agent 深度长文流水线技能包(DeepSeek Harness 原生插件):定题→并行检索(文献/数据/案例)→分析→大纲人在环确认→写作→批判→审计→审稿→修订→配图→终检交付,9 个独立角色 T1-T9 互不可替代(文献/数据/案例/分析/写作/批判/审计/终检/审稿),主控 = T0 调度 + T8 终检亲执行(T8 独立角色,执行者主控担任,不 spawn),T9 审稿可选默认选中学术必选,三角验证 + M 机械化硬门 + F 失败模式防御 + G14 中文 AI 痕迹闸 + 期刊匹配助手,用 dsh subagent 子代理编排。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
> 版本:v18.2.
|
|
1
|
+
> 版本:v18.2.4(DSH bundle 插件)
|
|
2
2
|
|
|
3
|
-
# 论衡快速开始指南(v18.2.
|
|
3
|
+
# 论衡快速开始指南(v18.2.4)
|
|
4
4
|
|
|
5
5
|
> **v2.3.0 升级(2026-08-21)**:角色编号重构(教训 #116)—— T6 案例检索 → T3 案例检索(三方并行检索员连贯 T1∥T2∥T3),T3-T8 顺延 + T7/T8 交换位置(终检 → T8 主控亲完成、批判 → T6 独立早期攻击、审计 → T7 形式审查)。新增 Phase 3.6 批判(T6 攻击 v2 含主人洞察)。
|
|
6
6
|
>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 论衡(lunheng-article-pipeline)— 多 Agent 深度长文流水线
|
|
2
2
|
|
|
3
|
-
> **DSH 原生插件(v18.2.
|
|
3
|
+
> **DSH 原生插件(v18.2.4)**:本仓库为 DSH bundle 技能包(`package.json` 的 `main` → `lib/index.js` 注册本技能 + `dsh.bundle.patch` → `cordis.patch.yml` 叠加三档 subagent 工具);结构性差异见 `SKILL.md` 的「🔧 DSH 环境说明」章节。
|
|
4
4
|
|
|
5
5
|
把一篇深度文章 / 论文的生产拆成 **9 个独立角色 T1-T9 + 6 个阶段**(v2.5.2-dsh.8 语义定案:T1-T9 互不可替代;Phase 1 为 T1 文献 ∥ T2 数据 ∥ T3 案例 三检索员三方真并行互不干涉,T3 任何量级必 spawn 含 0 条空卡协议;T6 批判伙伴 + T7 审计 + **T8 终检独立角色由主控 T0 亲执行** + T9 同行评审可选默认选中学术必选,v2.3.0 角色编号重构 + v2.4.0 加 T9),用 DSH 的 `subagent` 子代理编排,产出有**证据底座、反方论证、独立审计、人工核验节点**的交付物。
|
|
6
6
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: "lunheng-article-pipeline"
|
|
3
|
-
version: "18.2.
|
|
3
|
+
version: "18.2.4"
|
|
4
4
|
description: "论衡:DSH 原生多 Agent 深度长文流水线(学术论文 / 商业评论 / 行业分析 / 公众号)。9 个独立角色 T1-T9 + 主控(T0 调度 + T8 终检);三角验证 + M 门 + G 审计 + 修订回环 ≤2 轮 + 期刊匹配。适用:≥2000 字、证据须可追溯的长文(含 4 个人在环节点、1-3 小时流水线时长)。**不适用**:<2000 字短文与即时问答;文学创作(小说/诗歌/剧本);需数学推导或实验设计的理工科论文;营销软文;需要一手数据(问卷/访谈/田野/实验)而尚未投喂素材。"
|
|
5
5
|
whenToUse: "「何时该用」与「何时不该用」的完整判据已并入 description(v18.0.5:官方目录只渲染 name + description,本字段对模型不可见,保留仅供工具链与维护者阅读)。"
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
> 版本:v18.2.
|
|
8
|
+
> 版本:v18.2.4(DSH bundle 插件)
|
|
9
9
|
> **v2.5.2-dsh.8 角色语义定案(主人指令)**:**9 个角色 T1-T9 各自独立、不可相互替代**——T8 终检不是「主控兼做的杂活」而是独立角色(有独立角色卡),只是执行者由主控担任(**主控 = T0 调度 + T8 终检执行双重身份**),不 spawn 子代理;**T9 审稿可选、默认选中、学术论文必选**。
|
|
10
10
|
|
|
11
11
|
# 多 Agent 深度长文流水线(论文/深度文章生产)
|
|
@@ -94,7 +94,7 @@ whenToUse: "「何时该用」与「何时不该用」的完整判据已并入 d
|
|
|
94
94
|
|
|
95
95
|
## ⚡ 启动速查表
|
|
96
96
|
|
|
97
|
-
- 版本:v18.2.
|
|
97
|
+
- 版本:v18.2.4|角色:T0 主控(= T8 终检执行者)+ T1 文献 / T2 数据 / T3 案例 / T4 分析 / T5 写作 / T6 批判 / T7 审计 / T8 终检(主控亲执行)/ T9 审稿(默认选中,学术必选)
|
|
98
98
|
- Phase:0 定题 → 1 检索(T1∥T2∥T3) → 2 分析 → 2.5 大纲(人) → 3 写作 → **[3.1 G14 早闸]** → 3.5 洞察(人) → 3.6 批判 → 4 审计 → 4.5 审稿+G14 → 5 终检(人)
|
|
99
99
|
- 工具:subagent=派发(分档预设按角色选 subagent_retrieval/strong/audit)|list_agents=查看|todo_write=计划|web_search/web_fetch=检索|pwsh=命令|edit/write=文件
|
|
100
100
|
- 闸门:T2.5(检索→分析)/ T7.5(审计→终检);M 门 exit 0;修订回环双轨 ≤2 轮(A 轨)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 论衡 × DSH 能力面集成方案
|
|
2
2
|
|
|
3
|
-
> **版本**:v18.2.
|
|
3
|
+
> **版本**:v18.2.4(C 组落地;§一–§六 为 v18.0.2 原文,§七–§八 为 v18.2.1 新增,**§九 为 v18.2.2 新增**)
|
|
4
4
|
> **用途**:把论衡的既有机制(11 个门禁脚本 / 并行阶段 / 状态机 / 人在环闸门)**对齐 DSH 已有能力面**,替代平行自建。§一–§六 是**实施方案**,§七 是**落地状态表**,§八 是**可选配方**。
|
|
5
5
|
> **依据**:DSH 官方文档 `docs/cookbook/adding-a-tool.md`、`docs/tool-execution-pipeline.md`、`docs/subsystems/*.md`、`docs/capability-seams.md`(知识库副本见 `dsh-plugin-guide/references/official-docs/`;行号对快照 commit `d347e703…`)。
|
|
6
6
|
> **当前状态**:**C 组四项已启用**(原生只读工具 / `ctx.tools.guard()` 写保护 / `/lunheng-status` / 词预算门)、一项给配方(分档工具行→agent preset)、一项仍未接线(Phase 内并行→`workflow`,依官方用法限定「仅在用户明确要求 workflow 或大规模编排时」用,故**降级为按需**)。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 文档层规范 ↔ 机械门覆盖 对照表
|
|
2
2
|
|
|
3
|
-
> **版本**:v18.2.
|
|
3
|
+
> **版本**:v18.2.4(读者口径)/ v18.0.2(新增)
|
|
4
4
|
> **用途**:逐条勾稽「规范写了什么」与「机械门是否覆盖」,根治教训 **#139「规范从文档层到执行层断链」**——该教训在《观念与理念的关系》实战中**复现 3 次**(文末五节顺序 / 案例来源内容 / 基线编号误判)。
|
|
5
5
|
> **用法**:每次新增或修改规范时,在本表中加一行;每次版本 review 时逐行勾稽两问。
|
|
6
6
|
> **读者与时机(v18.0.5 补,冗余审计 §二.7)**:**论衡维护者文档**——改规范 / 加机检门 / 版本 review 时读;**运行期角色不加载本文件**(它刻意不在任何角色卡的「读」清单里:主控与 T1-T9 都不需要它)。入口 = `AGENTS.md` §文件修改操作约束 的验证步 + `references/_shared/M-Gate-Algorithm.md` 的「名实对齐」注。
|
|
@@ -47,10 +47,11 @@
|
|
|
47
47
|
| **闸门记录实据形态**(v18.2.1 补进 `机检硬格式.md §七`) | M-Exist-5 | 表头须含 `检查项/实据/结论`;逐项照抄模板清单(T2.5 八项 / T7.5 七项);实据须为机械证据(路径 / `exit N` / `node X.mjs` / sha256 / 数字+量词,v18.2.1 起 `exit=N` 亦可);结论词只允许 `✓/✗/N/A` |
|
|
48
48
|
| **素材加载清单编号写法**(v18.2.1 补进 `机检硬格式.md §八` + 清单模板) | M-Form-11 | 须有 `## 已加载` 段;**逐项**写法唯一保证被识别(v18.2.1 起范围写法 `[D01]-[D08]` 亦容忍并展开);「>90% 整卡通读」软提示仅在 卡池 ≥30 且 正文 ≥3000 汉字 时启用 |
|
|
49
49
|
|
|
50
|
-
## 二、历轮**新补上**的断链(按版本累积:v18.0.0 起;末尾 6 行为 v18.2.2)
|
|
50
|
+
## 二、历轮**新补上**的断链(按版本累积:v18.0.0 起;末尾 3 行为 v18.2.4、其上 6 行为 v18.2.2)
|
|
51
51
|
|
|
52
52
|
> **标题修正(v18.2.2)**:本表原写作「本轮(v18.0.0)」,但每轮修订都在此追加,标题**不再随版本漂移**——**逐行看「本轮修法」列里的版本号**即可知该行属哪一轮。
|
|
53
|
-
> **v18.2.2 的 6
|
|
53
|
+
> **v18.2.2 的 6 行**:数据点需求计数口径 / §11 精简段可被读到 / 承重墙清单可被读到 / AI 使用声明节可披露 / 证据包未到期的门 / 加载率比率可复算——**性质均为「门反向误判」或「两条规范冲突」**(而非「有规范无门」),即**门本身成了缺陷来源**。
|
|
54
|
+
> **v18.2.4 的 3 行**(末尾):版本点位两处**扫描盲区**(内联 `git tag` / 加粗版版本头)+ 入口路由字段的**来源**未被断言——**性质均为「有规范、门看着在管、实际扫不到/只断言存在性」**,即**门给出了虚假的安心**。
|
|
54
55
|
|
|
55
56
|
| 规范 | 原状态 | 本轮修法 |
|
|
56
57
|
|---|---|---|
|
|
@@ -74,6 +75,9 @@
|
|
|
74
75
|
| **AI 使用声明节可披露**(`AI-使用声明-template.md`) | ❌ **两条规范冲突**——该模板要求写披露语,M-Form-4 文末二级扫描却按「内部信息」判 P0(实测命中禁词「承重」) | M-Form-4 **豁免「AI 使用声明」一节**(其余四节照扫) |
|
|
75
76
|
| **证据包未到期的门**(`pipeline-readme` 闸门时序) | ❌ **门在错误阶段判死**——M-Exist-2 在 T7 审计 `drafts/` 时证据包尚由 T8 生成 → 判「0 个文件」P0,T5 修订轮无法关闭 | M-Exist-2 加**阶段感知**(`drafts/` + 空包 → N/A) |
|
|
76
77
|
| **加载率比率可复算**(`机检硬格式.md §八`) | ⚠️ **结论不可复算**——分子用整个已加载集(含索引外编号)→ 出现 `已加载 54 / 索引 52`(分子>分母) | M-Form-11 比率**先取交集** + 「白读」排除 `## 已跳过` |
|
|
78
|
+
| **版本点位处处一致(内联发布示例)**(`CONTRIBUTING.md §版本号约定`) | ❌ **无门但看着有门**——版本扫描的其余规则全跑在**技能目录**(`files = walk(ROOT)`),而 `git tag vX.Y.Z && git push origin vX.Y.Z` 这 7 处(`CONTRIBUTING.md` 2 + 5 语 README 各 1)全在**仓库根** → 四条规则全都扫不到,bump 时靠人工记得刷(v18.0.4→v18.2.4 连续五次人工) | 规则①/⑦ **同址补扫**(只认 `git tag` / `git push origin` 两形态,判 P1;散文历史注记不误伤)+ 回归用例 + 对照实验 |
|
|
79
|
+
| **版本点位处处一致(加粗版版本头)**(同上) | ❌ **无门但看着有门**——规则⑫ 旧正则 `[-*>#]*\s*版本:` 在标记与 `版本:` 之间**不允许夹 `**`** → `> **版本**:vX.Y.Z` 整条逃逸;**实测代价**:加固后首次运行即抓到 4 个文档**各带两个版本头**(第 5 行残留 `v2.5.1(2026-08-24)` 旧版本线头),从未被发现 | 正则改 `\*{0,2}`;4 处残留按「**一事实一处**」删除 + 回归用例 + 对照实验 |
|
|
80
|
+
| **入口路由字段须来自 `SKILL.md` 真源**(`SKILL.md` frontmatter 即模型侧路由唯一依据) | ❌ **门只断言存在性、不断言来源**——`tests/entry.test.mjs` 只要求「description 非空 / whenToUse 是非空字符串」,而**内置兜底 description 同样非空** → frontmatter 解析一旦失效(CRLF / BOM / 前置空行),测试**照样全绿** | 入口行尾+BOM 归一 + 显式闭合匹配 + 解析失败 `warn`;新增 `tests/entry-frontmatter.test.mjs` 用**行尾/编码变体**真跑 `apply`,断言「description **≠ 兜底**」 |
|
|
77
81
|
|
|
78
82
|
## 三、**仍无机械门**的规范(人工兜底,登记备查)
|
|
79
83
|
|
package/skills/lunheng-article-pipeline/references/agents/08-/347/273/210/346/243/200-finalizer.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 角色:终检员 Finalizer(T8)
|
|
2
2
|
|
|
3
|
-
> 版本:v18.2.
|
|
3
|
+
> 版本:v18.2.4(DSH bundle 插件)
|
|
4
4
|
|
|
5
5
|
> **角色独立性声明(v2.5.2-dsh.8 修订)**:T8 终检是**九个独立角色之一(T1-T9),不可被其他角色替代**。终检职责(M 门全复核 / 定稿 / 证据包 / 交付说明 / 失败模式兜底)只能由 T8 承担。
|
|
6
6
|
> **执行者 = 主控 T0 兼任**(T0 与 T8 是主控的两个身份:T0 统筹调度,T8 亲自执行终检)——T8 **不 spawn 子代理**,由主控以 T8 身份直接完成。
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
> 版本:v18.2.
|
|
1
|
+
> 版本:v18.2.4(DSH bundle 插件)
|
|
2
2
|
|
|
3
3
|
# 角色:同行评审 Peer Reviewer(T9,v2.4.0 新增)
|
|
4
4
|
|
|
5
|
-
> **版本**:v2.5.1(2026-08-24)
|
|
6
5
|
> **性质**:编辑-审稿双模式(pre-submission 同行评审)
|
|
7
6
|
> **能力档**:批判审计=顶配(候选池见 [`../_shared/模型路由.md`](../_shared/模型路由.md) §二)
|
|
8
7
|
> **借鉴**:academic-paper-reviewer(第三方同类插件,v2.2.0 论衡哲学化)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 主人确认单(人在环门)
|
|
2
2
|
|
|
3
|
-
> 版本:v18.2.
|
|
3
|
+
> 版本:v18.2.4(DSH bundle 插件)
|
|
4
4
|
> 用途:**四个**人在环确认节点通用——**Phase 0(定题)** / Phase 2.5(分析大纲)/ Phase 3.5(初稿结构 + 洞察落地)/ Phase 5(终稿交付)。
|
|
5
5
|
> 流程:主控把确认单写到 `<项目>/阶段确认-<阶段>.md` → **用 `ask_user_question` 向主人提问(§7)** → 主人确认或驳回 → 主控按回复继续或修订 **并把主人回复原文回填到 §6**。**未获确认不得跳过下一闸门;未回填 §6 不算闸门完成。**
|
|
6
6
|
> **⚠️ 文件名别名(v18.2.2 补,可发现性)**:本模板产出的是 **`阶段确认-<阶段>.md`**,故它**同时是**「阶段确认单模板」。若按 `references/templates/阶段确认-template.md` 搜索**搜不到**(本文件名历史上叫 `主人确认-template.md`)——**指的就是本文件**,不要转而拿旧项目里已有的 `阶段确认-*.md` 当模板(实战踩点:2026-09-12 全量测试的 Phase 0 即如此,主控据旧项目文件照抄,字段名与当轮模板已漂移)。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 交付说明 — <项目名>
|
|
2
2
|
|
|
3
|
-
> 版本:v18.2.
|
|
3
|
+
> 版本:v18.2.4(DSH bundle 插件)
|
|
4
4
|
> 位置:`run/<项目名>/final/交付说明.md` | 产出者:**T8 终检(主控亲执行)**
|
|
5
5
|
> 用途:**操作员报告**,给主人复核用。12 个固定字段见 [`../deliverables.md`](../deliverables.md) § 交付说明模板字段——**机检 M-Exist-7 逐字段核验**「字段齐备 + 有内容」,不得改名、不得省略、不得留 `<...>` 占位符。(v18.0.5 更正:本节旧版写 11,而模板实际 12 节,见 `deliverables.md:77`「由 11 显式化为 12」)
|
|
6
6
|
> **边界**:本文件不进入 `final/定稿.md`(论文),定稿也不得反引本文件内容(隔离由 M-Integrity-2 步骤 6 核验)。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 局限性(Acknowledged Limitations)— <项目名>
|
|
2
2
|
|
|
3
|
-
> 版本:v18.2.
|
|
3
|
+
> 版本:v18.2.4(DSH bundle 插件)
|
|
4
4
|
> 位置:`run/<项目名>/final/局限性.md` | 产出者:**T8 终检(主控亲执行)**
|
|
5
5
|
> 用途:**把「修订回环用尽仍未关闭的 P0/P1」变成显式可交付项**,而非留在报告里或悄悄放过。
|
|
6
6
|
> 触发条件(任一):① A 轨修订轮已达上限(v2.2.0 ≤2 轮)仍存 P0/P1;② 缺陷归属**上游阶段**(T1-T4 产物),T5 修订轮**无权修补**;③ 缺陷源于**产物尚未到期**(如 T7 阶段的证据包、图件);④ 机检门误判已被证伪但脚本未改。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 模型路由表 — <项目名>
|
|
2
2
|
|
|
3
|
-
> 版本:v18.2.
|
|
3
|
+
> 版本:v18.2.4(DSH bundle 插件)
|
|
4
4
|
> 来源:`node scripts/model-routing.mjs --json`(**只读脚本**:探测本机 provider×模型、本地可达性,并按四档能力表出建议)
|
|
5
5
|
> 位置:`run/<项目名>/model-routing.md` | 产出者:**主控**(Phase 0 定题时落盘;本机模型/provider 变化或发生回退时更新)
|
|
6
6
|
> 用途:① 派发时按表选工具档位;② 交付说明「成本指标」引用本表说明「各角色实际用哪个模型」;③ 回退留痕。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 阶段闸门记录 — <项目名>
|
|
2
2
|
|
|
3
|
-
> 版本:v18.2.
|
|
3
|
+
> 版本:v18.2.4(DSH bundle 插件)
|
|
4
4
|
> 用法:**抄两份**,各自只保留对应闸门那一段 → `audits/闸门记录-T2.5.md`、`audits/闸门记录-T7.5.md`
|
|
5
5
|
> 产出者:**主控(T0)**,在闸门判定**当场**写(不得事后补写;补写的记录失去证据价值)
|
|
6
6
|
> 用途:把「主控 LLM 兜底执行」的两道闸门变成**可核对的结构化记录**——机检 **M-Exist-5** 逐项核验:检查项齐备 / 实据是机械证据 / 结论词固定 / 判 ✗ 的行写了原因。
|
|
@@ -191,6 +191,31 @@ for (const [rel, p] of repoTargets) {
|
|
|
191
191
|
else if (normVer(m[0]) !== normVer(pkgVer)) errors.push(`[P0 版本一致性] ${rel} 写 ${m[0]} ≠ package.json=${pkgVer}(需 bump)`);
|
|
192
192
|
}
|
|
193
193
|
|
|
194
|
+
// ①/⑦ 补面(v18.2.4 新增,第三方审计「门必须覆盖它声称覆盖的规范」;主人指令「修」):
|
|
195
|
+
// **内联发布示例 `git tag vX.Y.Z && git push origin vX.Y.Z` 此前不在任何门里**。
|
|
196
|
+
// 它既非 `版本:` 前缀、也非安装 pin,而版本扫描的其余规则全都跑在**技能目录**(`files = walk(ROOT)`)
|
|
197
|
+
// —— 这 7 处却全在仓库根文件(`CONTRIBUTING.md` 2 处 + 5 语 README 各 1 处),故**四条版本规则全都扫不到**。
|
|
198
|
+
// `CONTRIBUTING.md` §版本号约定 早就记了这个漏点,代价是「每次 bump 靠人工记得刷」(截至 v18.2.3 已刷四次)。
|
|
199
|
+
// 故在此**与规则①/⑦ 同址**补扫(同属「仓库级文件版本点位」这一件事,不新增规则号 → 门数表述无需连带改)。
|
|
200
|
+
// 只认 `git tag` / `git push origin` 两种形态,不碰散文里的历史注记(那些必须允许留旧号)。
|
|
201
|
+
const inlineTagTargets = isRepoLayout
|
|
202
|
+
? [
|
|
203
|
+
...['README.md', 'README.zh.md', 'README.es.md', 'README.pt.md', 'README.hi.md'].map((f) => [f, join(REPO_ROOT, f)]),
|
|
204
|
+
['CONTRIBUTING.md', join(REPO_ROOT, 'CONTRIBUTING.md')],
|
|
205
|
+
['SECURITY.md', join(REPO_ROOT, 'SECURITY.md')],
|
|
206
|
+
]
|
|
207
|
+
: [];
|
|
208
|
+
for (const [rel, p] of inlineTagTargets) {
|
|
209
|
+
// 缺文件不在此报(规则① 与 ㉑ 已各报一次)——此处只负责「文件在、但内联 tag 写旧版」这一件事
|
|
210
|
+
if (!existsSync(p)) continue
|
|
211
|
+
readFileSync(p, 'utf8').split('\n').forEach((l, i) => {
|
|
212
|
+
const m = l.match(new RegExp('git (?:tag|push origin) v?(' + SEMVER + ')'));
|
|
213
|
+
if (m && normVer(m[1]) !== normVer(pkgVer)) {
|
|
214
|
+
errors.push(`[P1 内联 tag 版本漂移] ${rel}:${i + 1} 写 ${m[1]} ≠ package.json=${pkgVer}(每次 bump 必手工刷新此处)`);
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
|
|
194
219
|
for (const f of files) {
|
|
195
220
|
const rel = relative(ROOT, f).replaceAll('\\', '/');
|
|
196
221
|
const text = readFileSync(f, 'utf8');
|
|
@@ -423,11 +448,17 @@ if (existsSync(clPath)) {
|
|
|
423
448
|
}
|
|
424
449
|
|
|
425
450
|
// ⑫ 版本点位全量扫描(v2.5.2-dsh.13 新增:旧规则 ⑦ 只认 `> 版本:` 开头,漏检 `- 版本:`/标题内嵌等形态)
|
|
451
|
+
// v18.2.4 修订(第三方审计「门必须覆盖它声称覆盖的规范」;主人指令「修」):补一类**实测漏检**。
|
|
452
|
+
// · 漏点 B —— **加粗版版本头 `> **版本**:vX.Y.Z`**:旧正则 `[-*>#]*\s*版本:` 在标记与 `版本:`
|
|
453
|
+
// 之间**不允许夹 `**`**,故 `DSH-集成方案.md` / `规范-机械门对照表.md` 两处实际一直是人工刷的、
|
|
454
|
+
// 门判不到(人工一疏忽即静默停在旧版本)。修法:把 `**` 纳入可选标记(`\*{0,2}`)。
|
|
455
|
+
// (漏点 A「内联 git tag」在**仓库级文件**里,不在本规则的扫描面内——已补在规则①/⑦ 同址,
|
|
456
|
+
// 见上方 `inlineTagTargets`。本注释保留此交叉指引,防后来者以为它在此处。)
|
|
426
457
|
for (const f of files) {
|
|
427
458
|
if (isArchive(f)) continue;
|
|
428
459
|
const rel = relative(ROOT, f).replaceAll('\\', '/');
|
|
429
460
|
readFileSync(f, 'utf8').split('\n').forEach((l, i) => {
|
|
430
|
-
const m = l.match(new RegExp('^\\s*[-*>#]*\\s
|
|
461
|
+
const m = l.match(new RegExp('^\\s*[-*>#]*\\s*\\*{0,2}版本\\*{0,2}:v?(' + SEMVER + ')'));
|
|
431
462
|
if (m && normVer(m[1]) !== normVer(pkgVer)) {
|
|
432
463
|
errors.push(`[P0 版本点位漂移] ${rel}:${i + 1} 写 ${m[1]} ≠ package.json=${pkgVer}`);
|
|
433
464
|
}
|