dsh-thesis 1.0.1 → 2.0.2
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/LICENSE +1 -1
- package/NOTICE.md +1 -1
- package/README.md +51 -86
- package/docs/autopilot.md +73 -0
- package/docs/config.md +113 -0
- package/{DESIGN.md → docs/design.md} +69 -74
- package/docs/host-api.md +49 -6
- package/docs/release.md +138 -0
- package/docs/tools.md +76 -0
- package/docs/troubleshooting.md +88 -0
- package/docs/usage.md +87 -0
- package/lib/autopilot/index.d.ts +38 -0
- package/lib/autopilot/index.js +159 -0
- package/lib/autopilot/intent.d.ts +40 -0
- package/lib/autopilot/intent.js +82 -0
- package/lib/autopilot/messages.d.ts +23 -0
- package/lib/autopilot/messages.js +36 -0
- package/lib/autopilot/types.d.ts +60 -0
- package/lib/autopilot/types.js +10 -0
- package/lib/codewalk/engine.d.ts +1 -1
- package/lib/codewalk/engine.js +1 -1
- package/lib/codewalk/gate.d.ts +1 -1
- package/lib/codewalk/gate.js +1 -1
- package/lib/codewalk/host-types.d.ts +2 -31
- package/lib/codewalk/prestep.js +3 -3
- package/lib/codewalk/tools.js +2 -2
- package/lib/config.d.ts +17 -0
- package/lib/config.js +9 -1
- package/lib/dedup/index.js +0 -6
- package/lib/gates/messages.d.ts +7 -6
- package/lib/gates/messages.js +8 -5
- package/lib/index.d.ts +3 -1
- package/lib/index.js +10 -7
- package/lib/ingest/index.d.ts +1 -1
- package/lib/ingest/index.js +1 -3
- package/lib/intake/gate-rules.d.ts +1 -2
- package/lib/intake/gate-rules.js +2 -2
- package/lib/intake/index.d.ts +0 -17
- package/lib/intake/index.js +0 -51
- package/lib/intake/questions.d.ts +1 -1
- package/lib/intake/questions.js +1 -1
- package/lib/memory/recall.d.ts +1 -2
- package/lib/memory/recall.js +2 -2
- package/lib/paper/lib/layout.d.ts +1 -1
- package/lib/paper/lib/layout.js +2 -2
- package/lib/paper/lib/ledger.d.ts +1 -1
- package/lib/paper/lib/ledger.js +1 -1
- package/lib/paper/register.d.ts +2 -2
- package/lib/paper/register.js +2 -8
- package/lib/paper/tools/decision.js +1 -1
- package/lib/paper/tools/init.d.ts +1 -1
- package/lib/paper/tools/init.js +1 -1
- package/lib/ppt/index.d.ts +1 -2
- package/lib/ppt/index.js +1 -2
- package/lib/shared/define-tool.d.ts +1 -1
- package/lib/shared/define-tool.js +1 -1
- package/lib/shared/message-source.d.ts +21 -0
- package/lib/shared/message-source.js +19 -0
- package/package.json +17 -17
- package/skills/code-walkthrough/SKILL.md +5 -3
- package/skills/thesis-defense/SKILL.md +1 -1
- package/skills/thesis-pipeline/SKILL.md +3 -3
- package/lib/codewalk/commands.d.ts +0 -23
- package/lib/codewalk/commands.js +0 -168
- package/lib/commands.d.ts +0 -33
- package/lib/commands.js +0 -60
- package/lib/dedup/commands.d.ts +0 -21
- package/lib/dedup/commands.js +0 -93
- package/lib/ingest/commands.d.ts +0 -23
- package/lib/ingest/commands.js +0 -74
- package/lib/paper/commands.d.ts +0 -13
- package/lib/paper/commands.js +0 -84
- package/lib/ppt/commands.d.ts +0 -28
- package/lib/ppt/commands.js +0 -71
package/LICENSE
CHANGED
package/NOTICE.md
CHANGED
package/README.md
CHANGED
|
@@ -2,131 +2,96 @@
|
|
|
2
2
|
|
|
3
3
|
**把一堆材料变成一篇经得起查重与答辩的论文,和一个讲得清自己系统的你。**
|
|
4
4
|
|
|
5
|
-
[DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)
|
|
6
|
-
|
|
5
|
+
[DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 的单一插件。给它学校模板、
|
|
6
|
+
论文要求、实验数据、代码和参考文献,它先追问、再动手,按九个阶段推进:
|
|
7
7
|
|
|
8
8
|
**选题 → 开题 → 文献 → 设计 → 实现 → 测试 → 论文 → 合规 → 答辩**
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
纯 TypeScript,零运行时第三方依赖。
|
|
10
|
+
**没有斜杠命令。** 在论文工作区里开口说话,插件问一道选择题确认意图,然后自己一轮轮跑下去,
|
|
11
|
+
只在 G1-G4 人工关卡停下来让你拍板。全程留痕(台账 / 决定日志 / 检索记录 / 检查报告)。
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
纯 TypeScript,零运行时第三方依赖。对外只有三个命名空间:`thesis_*`、`fact_*`、`defense_code_*`。
|
|
15
14
|
|
|
16
15
|
## 安装
|
|
17
16
|
|
|
18
|
-
在 DSH 的**插件管理器里搜索 `dsh-thesis`** 装上,重启 dsh
|
|
17
|
+
在 DSH 的**插件管理器里搜索 `dsh-thesis`** 装上,重启 dsh。
|
|
19
18
|
|
|
20
|
-
|
|
19
|
+
从源码装(想改代码,或本机没有 pnpm):
|
|
21
20
|
|
|
22
21
|
```bash
|
|
23
|
-
git clone https://github.com/
|
|
24
|
-
npm install && npm run build # DSH 没有 TS
|
|
22
|
+
git clone https://github.com/booondenz/dsh-thesis.git && cd dsh-thesis
|
|
23
|
+
npm install && npm run build # DSH 没有 TS 加载器,必须先编译
|
|
25
24
|
dsh plugin --profile web add "$PWD" # 需要 pnpm
|
|
26
|
-
node scripts/install-into-profile.
|
|
25
|
+
node scripts/install-into-profile.ts --profile web # 没有 pnpm 时的兜底
|
|
27
26
|
```
|
|
28
27
|
|
|
29
|
-
卸载:插件管理器里移除,或 `dsh plugin --profile web remove dsh-thesis
|
|
28
|
+
卸载:插件管理器里移除,或 `dsh plugin --profile web remove dsh-thesis`。
|
|
30
29
|
|
|
31
|
-
|
|
32
|
-
`peerDependencies`,不满足就把该行静默 `disabled`(stderr 打印 `disabling profile plugin row`)。
|
|
33
|
-
本插件声明 `>=0.2.0-rc.2 <0.3.0-0`;跨小版本时先跑 `npm run test:host-load`(用宿主自己的预检函数判定)
|
|
34
|
-
与 `npm run test:host`(真实 cordis 装配),再把 range 改成实测过的版本。
|
|
30
|
+
## 第一次用
|
|
35
31
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
## 30 秒上手
|
|
39
|
-
|
|
40
|
-
装好并重启后,把材料丢进工作区(或告诉它绝对路径),在对话里说:
|
|
32
|
+
把材料放进论文目录(或告诉它绝对路径),在**该目录下**开会话说:
|
|
41
33
|
|
|
42
34
|
```
|
|
43
35
|
这是我的论文材料,帮我做毕业设计
|
|
44
36
|
```
|
|
45
37
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
> **把会话开在论文目录里**最省事:多数工具从会话 cwd 向上探测 `00-管理/进度台账.md` 来定位工作区。
|
|
50
|
-
> 也可以用 `config: { workspace: /path/to/你的论文 }` 显式指定(路径写错会直接报错,绝不写到别处)。
|
|
51
|
-
|
|
52
|
-
---
|
|
53
|
-
|
|
54
|
-
## 能力一览
|
|
55
|
-
|
|
56
|
-
| 环节 | 工具 | 要点 |
|
|
57
|
-
|---|---|---|
|
|
58
|
-
| 材料与要求 | `thesis_ingest` `thesis_intake` | docx/xlsx/pptx/pdf/md/csv/代码 → 文本与**代码结构**摘要;再逐题追问成意图规格,断点续问 |
|
|
59
|
-
| 工作区与关卡 | `thesis_init` `thesis_progress` `thesis_decide` | 九阶段目录 + 台账 + 决定日志;**G1-G4 关卡未过不许推进** |
|
|
60
|
-
| 文献 | `thesis_lit_search` `thesis_lit_save` `thesis_lit_note` | Semantic Scholar → DBLP → arXiv → Crossref 降级检索;**只认真实检索缓存,零假文献** |
|
|
61
|
-
| 写作与合规 | `thesis_review` `thesis_check` `thesis_stylecheck` `thesis_build` `thesis_originality` | 逐章评审 / 全文五项检查 / 去 AI 味自查 / 出 `论文.docx`(优先 pandoc,否则内置零依赖生成器)/ 本地降重度量 + 复测 |
|
|
62
|
-
| 答辩 | `thesis_defense` `thesis_slides` `defense_code_*` | 素材 + 六类问题库;Marp 兼容幻灯(含讲稿与证据锚点);代码演练把系统拆成讲得清的模块 |
|
|
63
|
-
| 跨会话事实 | `fact_search` `fact_remember` `fact_context` | SQLite 记住学校规范、导师要求、写作偏好;相关时自动放回上下文 |
|
|
64
|
-
|
|
65
|
-
斜杠命令 9 个:`/thesis-status` `/thesis-decide` `/thesis-lit` `/thesis-check` `/thesis-build`
|
|
66
|
-
`/thesis-ingest` `/thesis-intake` `/thesis-originality` `/thesis-defense`。
|
|
67
|
-
|
|
68
|
-
技能包 11 个(随插件发布,`thesis_init` 复制进论文仓库 `.dsh/skills/` 与论文一起 git 版本化):
|
|
69
|
-
`thesis-pipeline` `thesis-opener` `thesis-literature` `thesis-eng-design` `thesis-writing` `thesis-citation`
|
|
70
|
-
`thesis-defense` `code-walkthrough` `paper-intake` `paper-dedup` `thesis-inquiry`。
|
|
71
|
-
|
|
72
|
-
---
|
|
73
|
-
|
|
74
|
-
## 红线(写在护栏里,不是写在文档里)
|
|
75
|
-
|
|
76
|
-
1. **零假文献**:引用只能来自真实检索缓存,`thesis_lit_save` 拒绝缓存外的 id,`thesis_check` 复核双向一致。
|
|
77
|
-
2. **零假数据**:实验数据与运行结果必须来自真实运行;`thesis_originality` 明确禁止为降重改动数据与结论。
|
|
78
|
-
3. **人是作者**:G1-G4 关卡由工具强制;决定必须由你拍板。
|
|
79
|
-
4. **规范以学校文件为准**:模板缺失时用内置过渡模板并**显式标注「非学校模板」**,绝不假装合规。
|
|
80
|
-
5. **降重不是洗稿**:不接收费查重系统,报告里的重复率是**本地估算**,与学校结果不可等同(可回填对照)。
|
|
81
|
-
6. **不静默销毁数据**:读不出来 ≠ 不存在。读取失败时工具抛错并保持原文件不动,绝不用默认值覆盖。
|
|
82
|
-
|
|
83
|
-
---
|
|
84
|
-
|
|
85
|
-
## 已知边界
|
|
86
|
-
|
|
87
|
-
- **PDF 是尽力而为**:扫描版(无文本层)、对象流/加密 PDF 可能抽不出文字,会明确报原因而不是编造内容。
|
|
88
|
-
- **旧格式不支持**:`.doc`/`.xls`/`.ppt` 请先另存为新格式。
|
|
89
|
-
- **幻灯不自研生成器**:只产出 Marp 兼容 Markdown,`.pptx` 依赖外部 marp/pandoc;两者都缺时给出可执行命令与兜底路径。
|
|
90
|
-
- **子进程不可取消**:pandoc/marp/git 走 `spawnSync`,有超时但没有信号传递。
|
|
91
|
-
- **类型来自本地 shim**:为让仓库零依赖即可 `tsc` 通过,宿主契约声明在 `src/types/shims.d.ts`,真实签名核对见 [docs/host-api.md](./docs/host-api.md)。
|
|
92
|
-
- **代码演练语言矩阵**:内置 Go/TS/Python/Rust,其余语言需在配置里补 `gates`。
|
|
93
|
-
|
|
94
|
-
---
|
|
38
|
+
它会弹一道选择题(从零走到答辩 / 只补合规与答辩 / 只做答辩准备 / 先别自动跑),
|
|
39
|
+
选完就自动推进;撞上 G1-G4 关卡时在审批界面点「允许」或「拒绝」。
|
|
40
|
+
没有材料也能用:「我要做毕业设计,还没定题」。
|
|
95
41
|
|
|
96
42
|
## 配置
|
|
97
43
|
|
|
98
|
-
|
|
44
|
+
默认值都在,通常不用写。需要时在 profile 的 `cordis.patch.yml` 那一行里覆盖:
|
|
99
45
|
|
|
100
46
|
```yaml
|
|
101
47
|
- id: paper
|
|
102
48
|
name: dsh-thesis
|
|
103
49
|
config:
|
|
104
|
-
workspace:
|
|
105
|
-
|
|
106
|
-
similarity: { shingle: 4, threshold: 0.3 } # 原创性自查度量
|
|
107
|
-
ppt: { engine: auto } # auto | marp | pandoc | none
|
|
108
|
-
writingGate: true # 要求没立稳时拦下「开始写」
|
|
109
|
-
destructiveGate: true # 不可逆命令前提请拍板
|
|
50
|
+
workspace: D:/毕业论文/我的论文 # 缺省从会话 cwd 向上探测 00-管理/进度台账.md
|
|
51
|
+
autopilot: { maxGoalRounds: 20 } # 自动续跑的轮数上限(默认 40)
|
|
110
52
|
```
|
|
111
53
|
|
|
112
|
-
|
|
113
|
-
|
|
54
|
+
完整字段见 [docs/config.md](./docs/config.md)。
|
|
55
|
+
|
|
56
|
+
## 红线(写在护栏里,不是写在文档里)
|
|
114
57
|
|
|
115
|
-
|
|
58
|
+
1. **零假文献**:引用只能来自真实检索缓存,`thesis_lit_save` 拒绝缓存外的 id。
|
|
59
|
+
2. **零假数据**:数据与结果必须来自真实运行;降重不许改数据与结论。
|
|
60
|
+
3. **人是作者**:G1-G4 关卡由工具强制,决定必须由你拍板。
|
|
61
|
+
4. **规范以学校文件为准**:没有模板时用内置过渡模板并**显式标注「非学校模板」**。
|
|
62
|
+
5. **降重不是洗稿**:不接收费查重,报告里是本地估算,与学校结果不可等同(可回填对照)。
|
|
63
|
+
6. **不静默销毁数据**:读不出来 ≠ 不存在;读失败就抛错,绝不用默认值覆盖。
|
|
64
|
+
|
|
65
|
+
## 文档
|
|
66
|
+
|
|
67
|
+
| 文档 | 内容 |
|
|
68
|
+
|---|---|
|
|
69
|
+
| [docs/usage.md](./docs/usage.md) | 使用手册:第一次会话、九阶段、常见动作、产出物、中断续跑 |
|
|
70
|
+
| [docs/autopilot.md](./docs/autopilot.md) | 自动驾驶:四档意图、关卡拍板、何时不介入、降级与关闭 |
|
|
71
|
+
| [docs/tools.md](./docs/tools.md) | 21 个工具 + 11 个技能一览(名字即契约) |
|
|
72
|
+
| [docs/config.md](./docs/config.md) | 全部配置字段、默认值与约束 |
|
|
73
|
+
| [docs/troubleshooting.md](./docs/troubleshooting.md) | 装了没反应、没弹选择题、PDF/pptx 失败等 |
|
|
74
|
+
| [docs/design.md](./docs/design.md) | 设计文档与 ADR(架构、分层、质量策略、已知边界) |
|
|
75
|
+
| [docs/host-api.md](./docs/host-api.md) | 宿主契约:用到的 DSH 接口与实测行为 |
|
|
76
|
+
| [docs/release.md](./docs/release.md) | 发版:tag → GitHub Actions → npm(含 provenance)|
|
|
116
77
|
|
|
117
78
|
## 开发
|
|
118
79
|
|
|
119
80
|
```bash
|
|
120
81
|
npm install && npm run build # tsc → lib/
|
|
121
|
-
npm test # node --test
|
|
122
|
-
npm run verify #
|
|
82
|
+
npm test # node --test(Node 24 直接跑 .ts)
|
|
83
|
+
npm run verify # build + 两个 typecheck + 全部单测 + 审计 + 端到端
|
|
123
84
|
```
|
|
124
85
|
|
|
125
|
-
|
|
126
|
-
`
|
|
86
|
+
仓库里**没有 JS 源文件**:`src/`、`scripts/`、`tests/` 全是 `.ts`,直接由 Node 执行(需要 Node ≥ 22.18);
|
|
87
|
+
`lib/` 只是 `tsc` 产物(已 gitignore,发布时作为编译后的 JS 提供)。
|
|
88
|
+
|
|
89
|
+
质量分层:单测/契约、真实场景端到端、真实 cordis 装配、真实 dsh 引擎装载、对外表面审计
|
|
90
|
+
(见 [docs/design.md](./docs/design.md) §9)。
|
|
127
91
|
|
|
128
|
-
|
|
92
|
+
**发版**:打 tag 即发布,由 GitHub Actions 跑构建、校验与 `npm publish --provenance`,
|
|
93
|
+
见 [docs/release.md](./docs/release.md)。
|
|
129
94
|
|
|
130
95
|
## 许可
|
|
131
96
|
|
|
132
|
-
MIT
|
|
97
|
+
MIT。来源声明见 [NOTICE.md](./NOTICE.md)。
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# 自动驾驶
|
|
2
|
+
|
|
3
|
+
插件不提供任何斜杠命令。它在论文工作区里**自己把流程推起来**,只在两处需要你:
|
|
4
|
+
**开头选一次意图**、**过关卡时拍一次板**。
|
|
5
|
+
|
|
6
|
+
## 一次完整流程
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
你说一句话
|
|
10
|
+
↓
|
|
11
|
+
[agent/pre-step] 查出「论文工作区 + 主 agent + 还没有意图规格」
|
|
12
|
+
↓ ctx.userQuestions.ask ← 一道选择题(只有一次)
|
|
13
|
+
你选:从零走到答辩 / 只补合规与答辩 / 只做答辩准备 / 先别自动跑
|
|
14
|
+
↓
|
|
15
|
+
写进 00-管理/决定日志.md (答辩时这就是「为什么这么推进」的证据)
|
|
16
|
+
↓
|
|
17
|
+
ctx.goals.create(...) → 宿主的 goal-round-driver 接手,一轮轮自动续跑
|
|
18
|
+
↓
|
|
19
|
+
注入 operating contract (怎么推进、哪些活扇给子 agent、产出必须落盘、不许编数据)
|
|
20
|
+
↓
|
|
21
|
+
┌── 模型干活(可以开子 agent 并行) ──┐
|
|
22
|
+
│ 过 G1-G4? │
|
|
23
|
+
│ [tools/pre-execute] 拦成 ask ──────┼──→ 你在审批界面点「允许 / 拒绝」
|
|
24
|
+
└─────────────────────────────────────┘
|
|
25
|
+
↓
|
|
26
|
+
update_goal complete → 给一页「做了什么 / 待你确认」
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## 四档意图
|
|
30
|
+
|
|
31
|
+
| 选项 | 目标 |
|
|
32
|
+
|---|---|
|
|
33
|
+
| 从零走到答辩(九阶段全跑) | 材料 → 追问 → 文献 → 设计 → 实现 → 测试 → 论文 → 合规 → 答辩 |
|
|
34
|
+
| 已有材料/初稿,补齐合规与答辩 | 不重写正文,只补检查、降重自查、答辩材料 |
|
|
35
|
+
| 只做答辩准备 | 素材 + 问题库 + 幻灯 + 代码演练 |
|
|
36
|
+
| 先别自动跑,我自己来 | 不建目标、不注入指令,照常一问一答 |
|
|
37
|
+
|
|
38
|
+
## 它什么时候**不**介入
|
|
39
|
+
|
|
40
|
+
这四条都写成了测试,不靠自觉:
|
|
41
|
+
|
|
42
|
+
- **不是论文工作区**:`findThesisRoot` 找不到 `00-管理/进度台账.md`,完全安静(别的项目里装了也不打扰)。
|
|
43
|
+
- **子 agent**:委派深度 > 0 一律跳过,否则每开一个子 agent 又问一遍。
|
|
44
|
+
- **已经有意图规格**:`00-管理/意图规格.md` 存在的会话只记一条日志,不重复问。
|
|
45
|
+
- **同一个 agent 只问一次**:第二轮起不再打扰。
|
|
46
|
+
|
|
47
|
+
## 降级路径(宿主缺服务时)
|
|
48
|
+
|
|
49
|
+
| 缺什么 | 结果 |
|
|
50
|
+
|---|---|
|
|
51
|
+
| 没有 `userQuestions` 服务 / 选择题没渲染出来 | 不问,也不注入指令,本轮就是普通对话(日志会写原因)|
|
|
52
|
+
| 没有 `goals` 服务 | 只推进当前一轮,不会自动续轮 |
|
|
53
|
+
| 没有 `commands` 服务 | 无影响:本插件从来不用命令面 |
|
|
54
|
+
|
|
55
|
+
## 关掉它
|
|
56
|
+
|
|
57
|
+
```yaml
|
|
58
|
+
- id: paper
|
|
59
|
+
name: dsh-thesis
|
|
60
|
+
config:
|
|
61
|
+
autopilot:
|
|
62
|
+
enabled: false # 退回「纯工具 + 技能」模式
|
|
63
|
+
gateApproval: true # false = 仍然自动跑,但关卡不再拦人
|
|
64
|
+
maxGoalRounds: 40 # 调小,防跑飞
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## 排查
|
|
68
|
+
|
|
69
|
+
- 说了话但**没弹选择题**:看会话日志里有没有 `dsh-thesis: 意图选择题没有拿到答案` 或
|
|
70
|
+
`宿主没有 userQuestions 服务`。这两种情况下插件有意不猜你的意图。
|
|
71
|
+
- 跑了**一轮就停**:日志里找 `宿主没有 goals 服务`——说明这套组合不支持自动续轮。
|
|
72
|
+
- **关卡没问就过了**:检查配置里 `autopilot.gateApproval` 是否为 `false`。
|
|
73
|
+
- 想重新选一次意图:删掉 `00-管理/意图规格.md`(或新开一个尚无规格的工作区会话)。
|
package/docs/config.md
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# 配置
|
|
2
|
+
|
|
3
|
+
所有字段都有出厂默认值,通常不用写任何配置。`PAPER_DEFAULTS`([src/config.ts](../src/config.ts))
|
|
4
|
+
是 schema `.default()` 与代码侧回退的**单一来源**:缺配置绝不会退化成「静默关闸门」。
|
|
5
|
+
|
|
6
|
+
## 写在哪
|
|
7
|
+
|
|
8
|
+
profile 的 `cordis.patch.yml` 里,那一行插件的 `config:` 下面:
|
|
9
|
+
|
|
10
|
+
```yaml
|
|
11
|
+
- id: paper
|
|
12
|
+
name: dsh-thesis
|
|
13
|
+
config:
|
|
14
|
+
workspace: D:/毕业论文/我的论文
|
|
15
|
+
autopilot: { maxGoalRounds: 20 }
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
只想改少数几项时,只写那几项即可(其余补默认值)。嵌套块写法:
|
|
19
|
+
|
|
20
|
+
```yaml
|
|
21
|
+
similarity: { shingle: 4, threshold: 0.3 }
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## 全部字段
|
|
25
|
+
|
|
26
|
+
### 工作区与记忆
|
|
27
|
+
|
|
28
|
+
| 字段 | 默认 | 说明 |
|
|
29
|
+
|---|---|---|
|
|
30
|
+
| `workspace` | 无 | 论文工作区根。缺省从会话 cwd 向上探测 `00-管理/进度台账.md`;**配了就只认它**,路径写错直接报错 |
|
|
31
|
+
| `memoryPath` | `$DSH_HOME/dsh-thesis-memory.db` | 跨会话事实库(SQLite)|
|
|
32
|
+
|
|
33
|
+
### 材料与追问
|
|
34
|
+
|
|
35
|
+
| 字段 | 默认 | 说明 |
|
|
36
|
+
|---|---|---|
|
|
37
|
+
| `ingest.maxBytes` | `33554432`(32 MiB)| 单个文件读取上限,超过则拒绝并说明 |
|
|
38
|
+
| `ingest.maxChars` | `60000` | 单次摄取写回模型的最大字符数,超出截断并标注 |
|
|
39
|
+
| `intake.maxQuestions` | `12` | 一道选择题之外,追问环节最多问几个问题 |
|
|
40
|
+
| `intake.specRel` | `00-管理/意图规格.md` | 意图规格落盘位置(相对工作区根)|
|
|
41
|
+
|
|
42
|
+
### 原创性自查
|
|
43
|
+
|
|
44
|
+
| 字段 | 默认 | 说明 |
|
|
45
|
+
|---|---|---|
|
|
46
|
+
| `similarity.shingle` | `4` | 指纹窗口(中文字符数;英文按 4 字符近似词)|
|
|
47
|
+
| `similarity.threshold` | `0.3` | 判定高风险的包含率阈值(0..1,越大越宽松)|
|
|
48
|
+
| `similarity.minChars` | `30` | 参与比对的最短段落长度,更短的不判重(标题、公式行)|
|
|
49
|
+
|
|
50
|
+
### 写作风格自查
|
|
51
|
+
|
|
52
|
+
| 字段 | 默认 | 说明 |
|
|
53
|
+
|---|---|---|
|
|
54
|
+
| `stylecheck.reportRel` | `08-合规/AI味自查报告.md` | 报告落盘位置 |
|
|
55
|
+
| `stylecheck.maxParagraphChars` | `260` | 触发「长段落无锚点」判断的最短长度 |
|
|
56
|
+
|
|
57
|
+
### 答辩
|
|
58
|
+
|
|
59
|
+
| 字段 | 默认 | 说明 |
|
|
60
|
+
|---|---|---|
|
|
61
|
+
| `ppt.engine` | `auto` | `auto` / `marp` / `pandoc` / `none`;auto 探测不到就只产出 Markdown |
|
|
62
|
+
| `ppt.theme` | `default` | 写进 Marp frontmatter 的 `theme` |
|
|
63
|
+
| `ppt.timeoutMs` | `120000` | 单次外部转换超时 |
|
|
64
|
+
| `defense.materialsRel` | `07-答辩/答辩素材.md` | 答辩素材位置 |
|
|
65
|
+
| `defense.questionsRel` | `07-答辩/预答辩问题库.md` | 问题库位置 |
|
|
66
|
+
| `defense.defaultPages` | `11` | 幻灯默认页数(规范 10-12)|
|
|
67
|
+
|
|
68
|
+
### 代码演练
|
|
69
|
+
|
|
70
|
+
| 字段 | 默认 | 说明 |
|
|
71
|
+
|---|---|---|
|
|
72
|
+
| `codeWalkthrough.stateDir` | `.paper` | 演练状态目录(相对会话 cwd)|
|
|
73
|
+
| `codeWalkthrough.gates` | Go / TS / Python / Rust | 语言 → 编译验证门命令,例如 `go: { build: ['go', 'build', './...'] }` |
|
|
74
|
+
| `codeWalkthrough.maxCapturedOutput` | `8000` | 每条门命令输出保留的字符数 |
|
|
75
|
+
|
|
76
|
+
### 自动驾驶
|
|
77
|
+
|
|
78
|
+
| 字段 | 默认 | 说明 |
|
|
79
|
+
|---|---|---|
|
|
80
|
+
| `autopilot.enabled` | `true` | 总开关;`false` 退回「纯工具 + 技能」|
|
|
81
|
+
| `autopilot.maxGoalRounds` | `40` | 目标最多自动跑多少轮(防跑飞)|
|
|
82
|
+
| `autopilot.gateApproval` | `true` | 过 G1-G4 是否必须由人在审批界面拍板 |
|
|
83
|
+
|
|
84
|
+
### 事实回灌
|
|
85
|
+
|
|
86
|
+
| 字段 | 默认 | 说明 |
|
|
87
|
+
|---|---|---|
|
|
88
|
+
| `recall.maxEntries` | `4` | 一次最多回灌几条事实 |
|
|
89
|
+
| `recall.maxChars` | `600` | 回灌卡片的最大字符数 |
|
|
90
|
+
| `recall.minKeywordLength` | `2` | 多短的关键词不参与匹配 |
|
|
91
|
+
|
|
92
|
+
### 闸门
|
|
93
|
+
|
|
94
|
+
| 字段 | 默认 | 说明 |
|
|
95
|
+
|---|---|---|
|
|
96
|
+
| `writingGate` | `true` | 要开写但要求没谈清时,注入指令强制先追问 |
|
|
97
|
+
| `writingIntentPatterns` | 内置 | 判定「要开写」的正则列表 |
|
|
98
|
+
| `criteriaMarkers` | 内置 | 命中即视为已带验收标准、不再拦截的正则 |
|
|
99
|
+
| `bypassMarkers` | 内置 | 用户显式授权「直接写」的短语 |
|
|
100
|
+
| `maxQuestions` | `3` | 注入指令允许模型一次提出的最大问题数 |
|
|
101
|
+
| `destructiveGate` | `true` | 不可逆命令执行前提请拍板 |
|
|
102
|
+
| `destructiveToolNames` | `['bash']` | 参与高危检测的工具名 |
|
|
103
|
+
| `destructiveRules` | 内置 | 高危规则(标签 + 正则)|
|
|
104
|
+
|
|
105
|
+
> 在本仓库的开发环境里,命令走 `pwsh` 而不是 `bash`:想覆盖 PowerShell 命令,
|
|
106
|
+
> 把 `destructiveToolNames` 改成 `['bash', 'pwsh']`,或直接用默认规则集的等价正则。
|
|
107
|
+
|
|
108
|
+
## 校验与默认值的保证
|
|
109
|
+
|
|
110
|
+
- 配置 schema 由 schemastery 编译,宿主启动前校验;写错类型会在**装载时**报错,不会带病运行。
|
|
111
|
+
- 新增字段必须同时进 `Config`、`PAPER_DEFAULTS`、`resolveConfig` 三处;缺一处会被
|
|
112
|
+
`npm run test:sandbox` 的「默认值来源一致」用例抓住。
|
|
113
|
+
- 开关默认值必须是**开**:缺配置不等于关闸门。
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 设计文档
|
|
2
|
+
|
|
3
|
+
> 这是 dsh-thesis 的设计与决策记录(ADR)。**怎么用**看 [usage.md](./usage.md),
|
|
4
|
+
> **字段怎么填**看 [config.md](./config.md),**工具叫什么**看 [tools.md](./tools.md)。
|
|
2
5
|
|
|
3
6
|
**一句话**:让一个对流程不了解的本科生,把「学校模板 + 论文要求 + 实验数据 + 代码 + 参考文献」这堆材料,
|
|
4
7
|
在 AI 的带教下变成**一篇真实系统与真实数据背书、符合学校规范、经得起查重与答辩的论文**,
|
|
@@ -29,7 +32,7 @@
|
|
|
29
32
|
|
|
30
33
|
```
|
|
31
34
|
┌──────────────────────────────────────────────────────────────────────┐
|
|
32
|
-
│ DSH(Web / CLI
|
|
35
|
+
│ DSH(Web / CLI):自然语言;插件自己问一道选择题、自己续跑 │
|
|
33
36
|
├──────────────────────────────────────────────────────────────────────┤
|
|
34
37
|
│ 单一插件 dsh-thesis(Cordis 插件,纯 TypeScript,一行 cordis.patch.yml)│
|
|
35
38
|
│ │
|
|
@@ -54,12 +57,12 @@
|
|
|
54
57
|
|---|---|---|
|
|
55
58
|
| `src/index.ts` | 唯一装配层:`apply()` 调各模块 register,最后装闸门 | `name` / `inject` / `Config` / `apply` |
|
|
56
59
|
| `src/config.ts` | 统一配置 schema + 默认值单一来源 + `resolveConfig` | `Config` / `PAPER_DEFAULTS` |
|
|
57
|
-
| `src/
|
|
60
|
+
| `src/autopilot/**` | 自动驾驶:启动选择题 + 建目标自动续轮 + 关卡拍板(不注册任何命令) | `installAutopilot` |
|
|
58
61
|
| `src/shared/**` | 工具胶水、`definePaperTool`、文本与 fs 错误工具、`spawnCommand` | `definePaperTool` 等 |
|
|
59
62
|
| `src/gates/**` | 写作意图闸门(`agent/pre-step`)+ 不可逆操作闸门(`tools/pre-execute`) | `installWritingGate` / `installDangerousGate` |
|
|
60
63
|
| `src/ingest/**` | ZIP/OOXML/PDF 解析 → 文本;源码目录 → **代码结构摘要**(不贴正文) | `registerIngest` |
|
|
61
64
|
| `src/intake/**` | 问题库 + 状态机 + 意图规格渲染 + 规格闸门 | `registerIntake` |
|
|
62
|
-
| `src/paper/**` | 论文流水线(纯逻辑 + 工具 +
|
|
65
|
+
| `src/paper/**` | 论文流水线(纯逻辑 + 工具 + 子命令词) | `registerPaper` |
|
|
63
66
|
| `src/dedup/**` | 归一化 + 相似度 + 改写处方 + 报告 | `registerDedup` |
|
|
64
67
|
| `src/ppt/**` | 幻灯计划 + Marp 渲染 + 转换器探测 | `registerPpt` |
|
|
65
68
|
| `src/codewalk/**` | 代码演练:阶段状态机 + 验证门 + 可评分追问 | `registerCodewalk` |
|
|
@@ -83,81 +86,40 @@
|
|
|
83
86
|
|
|
84
87
|
### 3.1 工具(21 个,三个命名空间)
|
|
85
88
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
| 工具 | 学生视角的一句话 |
|
|
89
|
-
|---|---|
|
|
90
|
-
| `thesis_ingest` | 把我的材料读进来(docx/xlsx/pptx/pdf/csv/代码 → 文本与结构摘要 + 材料清单) |
|
|
91
|
-
| `thesis_intake` | 一次问我一个要求问题,问完写成《意图规格》 |
|
|
92
|
-
| `thesis_init` | 建论文工作区(目录、台账、决定日志、七章模板、技能包) |
|
|
93
|
-
| `thesis_progress` | 看进度 / 过闸门 G1-G4 |
|
|
94
|
-
| `thesis_decide` | 记下我为什么这么定(答辩要用的证据) |
|
|
95
|
-
| `thesis_lit_search` / `thesis_lit_save` / `thesis_lit_note` | 真实检索文献 / 收录进 refs.bib / 生成阅读笔记 |
|
|
96
|
-
| `thesis_review` | 单章六项评审(字数、大纲、引用、图表编号、未完成标记、G2 清单) |
|
|
97
|
-
| `thesis_check` | 全文五项检查(引用双向一致、字数、编号、术语、学校模板探测) |
|
|
98
|
-
| `thesis_stylecheck` | 写作风格自查(六条启发式,附行号与改写建议) |
|
|
99
|
-
| `thesis_build` | 出论文 `.docx`(优先 pandoc + 学校模板,无 pandoc 用内置零依赖生成器) |
|
|
100
|
-
| `thesis_originality` | 原创性自查:scan 定位高风险段落 → verify 复测降幅 → report 汇总 |
|
|
101
|
-
|
|
102
|
-
**`thesis_*` 的答辩部分**
|
|
103
|
-
|
|
104
|
-
| 工具 | 学生视角的一句话 |
|
|
105
|
-
|---|---|
|
|
106
|
-
| `thesis_defense` | 提取答辩素材 + 六类必问问题库(附证据锚点) |
|
|
107
|
-
| `thesis_slides` | 生成 10-12 页 Marp 幻灯,并可选转换为 `.pptx` |
|
|
108
|
-
|
|
109
|
-
**`defense_code_*`:代码演练(答辩层)**
|
|
110
|
-
|
|
111
|
-
| 工具 | 学生视角的一句话 |
|
|
112
|
-
|---|---|
|
|
113
|
-
| `defense_code_status` | 我的系统我讲得清吗(阶段、里程碑、验证门、未通过的问题) |
|
|
114
|
-
| `defense_code_next` | 下一个该弄懂的模块(含 todo 与评分要点) |
|
|
115
|
-
| `defense_code_update` | 登记/推进/评分/重试(每次改动立即落盘) |
|
|
116
|
-
|
|
117
|
-
**`fact_*`:跨会话事实**
|
|
89
|
+
`thesis_*` / `defense_code_*` / `fact_*` 三组,名字即契约(改名就是破坏性变更)。
|
|
90
|
+
**逐个工具的用途、参数与边界见 [tools.md](./tools.md)**,这里只保留设计约束:
|
|
118
91
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
92
|
+
- 工具名与命名空间不允许游离:`npm run audit` 断言注册数恰好 21、且全落在三个前缀内;
|
|
93
|
+
- 每个工具都必须有 `output.schema` 与 `output.render`,返回值是**有界字符串**(不返回对象、不做流式);
|
|
94
|
+
- 工具只操作论文工作区里的东西,跨会话的东西一律走 `fact_*`,两者不混用。
|
|
95
|
+
### 3.2 命令面:**一条斜杠命令都没有**
|
|
122
96
|
|
|
123
|
-
|
|
97
|
+
`ctx.commands` 一次都不注册。人不再操作命令行,入口换成两条宿主事件:
|
|
124
98
|
|
|
125
|
-
|
|
126
|
-
|
|
99
|
+
| 事件 | 插件做什么 | 人看到什么 |
|
|
100
|
+
|---|---|---|
|
|
101
|
+
| `agent/pre-step` | 认出「论文工作区 + 主 agent + 还没定过意图」→ 问**一道**选择题(`ctx.userQuestions.ask`)→ 答案写进决定日志 → `ctx.goals.create` 建目标(宿主 `goal-round-driver` 此后自动续轮)→ 注入 operating contract | 会话刚开始时的一个选项框 |
|
|
102
|
+
| `tools/pre-execute` | 模型要过 G1-G4 时把决策改成 `ask` | 审批界面的允许 / 拒绝 |
|
|
127
103
|
|
|
128
|
-
|
|
129
|
-
|
|
104
|
+
两条铁律:**只对主 agent 生效**(`delegationDepthOf` 同款规则:头里的委派深度 > 0 一律跳过,
|
|
105
|
+
否则子 agent 会再问一遍)、**只对论文工作区生效**(`findThesisRoot` 找不到台账就完全不介入,
|
|
106
|
+
别的项目里装了也不受打扰)。取舍与代价见 ADR-15;`npm run audit` 把「命令注册数必须是 0」变成断言。
|
|
130
107
|
|
|
131
108
|
---
|
|
132
109
|
|
|
133
110
|
## 4. 配置契约
|
|
134
111
|
|
|
135
112
|
所有字段都有出厂默认值,`PAPER_DEFAULTS` 是 schema `.default()` 与代码侧回退的**单一来源**
|
|
136
|
-
|
|
113
|
+
(绝不让「缺配置」退化成「静默关闸门」)。配置面只用论文领域词汇,不引入别的概念体系。
|
|
137
114
|
|
|
138
|
-
|
|
139
|
-
export interface PaperConfig extends GateOptions {
|
|
140
|
-
workspace?: string // 缺省从会话 cwd 向上探测 00-管理/进度台账.md
|
|
141
|
-
memoryPath?: string // 缺省 $DSH_HOME/paper-memory.db
|
|
142
|
-
ingest?: Partial<IngestOptions>
|
|
143
|
-
intake?: Partial<IntakeOptions>
|
|
144
|
-
similarity?: Partial<SimilarityOptions>
|
|
145
|
-
stylecheck?: Partial<StylecheckOptions>
|
|
146
|
-
ppt?: Partial<PptOptions>
|
|
147
|
-
defense?: Partial<DefenseOptions>
|
|
148
|
-
codeWalkthrough?: Partial<CodeWalkthroughOptions>
|
|
149
|
-
recall?: Partial<RecallOptions>
|
|
150
|
-
}
|
|
151
|
-
```
|
|
115
|
+
**字段清单、默认值、取值范围与 YAML 示例见 [config.md](./config.md)。**
|
|
152
116
|
|
|
153
|
-
|
|
154
|
-
`destructiveGate`(不可逆命令前提请人类拍板),以及它们各自的模式列表与 `maxQuestions`。
|
|
155
|
-
|
|
156
|
-
**`workspace` 的语义是确定的**:配置了就只认它;该路径下没有台账时**明确报错**,
|
|
157
|
-
绝不悄悄退回到 cwd 探测去写到别的目录。
|
|
158
|
-
|
|
159
|
-
---
|
|
117
|
+
两条设计约束(写在这里是因为它们属于架构决定,不属于字段说明):
|
|
160
118
|
|
|
119
|
+
1. 新增字段必须同时进 `Config`(schemastery schema)、`PAPER_DEFAULTS`、`resolveConfig` 三处,
|
|
120
|
+
缺一处就会被 `npm run test:sandbox` 的「默认值来源一致」用例抓住;
|
|
121
|
+
2. 开关的默认值必须是**开**:缺配置绝不能等于关闸门(`writingGate` / `destructiveGate` /
|
|
122
|
+
`autopilot.gateApproval` 都遵守这条)。
|
|
161
123
|
## 5. 领域闭环:要求与被约束的产出物必须可达
|
|
162
124
|
|
|
163
125
|
追问问题声明它影响哪些产出物:`affects: IntakeAffect[]`。这不是描述性文字,
|
|
@@ -187,7 +149,7 @@ export type IntakeAffect =
|
|
|
187
149
|
|
|
188
150
|
`dsh plugin add` 一次装完,一个 `Config`,一套技能,模块间共享上下文(intake 写规格、写作读规格、
|
|
189
151
|
原创性自查读章节、幻灯读答辩素材)。代价是包变大;用「目录即模块 + 无跨模块反向依赖」控制耦合。
|
|
190
|
-
|
|
152
|
+
答辩能力横跨幻灯与代码演练,因此两者的装配都在装配层(`src/index.ts`)完成,
|
|
191
153
|
而不是让 `ppt/` 与 `codewalk/` 互相依赖。
|
|
192
154
|
|
|
193
155
|
### ADR-2 材料先追问、后动手
|
|
@@ -284,13 +246,41 @@ DSH 的 profile 预检(`dsh-app-boot` 的 `evaluatePluginCompatibility`,在
|
|
|
284
246
|
1. 声明写成**有下界的 range**:`>=<实测版本> <下一小版本>-0`。
|
|
285
247
|
末尾的 `-0` 不是装饰:`<0.3.0` 在 `includePrerelease: true` 下会把 `0.3.0-rc.1`
|
|
286
248
|
也算进去,`<0.3.0-0` 才是真正的「不跨小版本」。
|
|
287
|
-
2. 判据不自己实现:`scripts/lib/host-compat.
|
|
249
|
+
2. 判据不自己实现:`scripts/lib/host-compat.ts` 直接 import 已安装的
|
|
288
250
|
`dsh-app-boot`,用宿主自己的函数判断宿主自己的规则(同源,不会漂移)。
|
|
289
251
|
3. 两处强制执行:`npm run test:host-load`(本仓库 manifest **与已安装副本**两份都查,
|
|
290
|
-
因为 preflight 读的是后者)与 `prepublishOnly` 的 `scripts/prepublish-guard.
|
|
252
|
+
因为 preflight 读的是后者)与 `prepublishOnly` 的 `scripts/prepublish-guard.ts`
|
|
291
253
|
(跨小版本后忘了改声明就发不出去)。
|
|
292
254
|
4. 跨小版本时先跑 `npm run test:host` + `npm run test:host-load`,再改 range 的下界。
|
|
293
255
|
|
|
256
|
+
### ADR-15 不提供斜杠命令,插件在后台把流程推起来
|
|
257
|
+
|
|
258
|
+
命令是给人操作 CLI 的入口。这套流程真正的主角是模型与流水线,人只需要在两处出现:
|
|
259
|
+
**开头选一次意图**、**过关卡时拍一次板**。给他们九条命令(后来收敛成一条 + 九个动词)
|
|
260
|
+
是把「操作界面」当成了产品,而用户要的是「我说一句、它自己跑」。
|
|
261
|
+
|
|
262
|
+
于是命令面整体删除(ctx.commands 一次都不注册),换成两条宿主事件:
|
|
263
|
+
|
|
264
|
+
1. gent/pre-step:论文工作区 + 主 agent + 还没有意图规格时,用 ctx.userQuestions.ask
|
|
265
|
+
问**一道**选择题(四档:从零走到答辩 / 只补合规与答辩 / 只做答辩准备 / 先别自动跑)。
|
|
266
|
+
选定后把意图写进决定日志、ctx.goals.create 建目标(宿主的 goal-round-driver 按它自动续轮),
|
|
267
|
+
再注入一条 operating contract(怎么推进、怎么并行、哪里必须停)。
|
|
268
|
+
2. ools/pre-execute:模型要过 G1-G4 时把决策改成 sk,由人在审批界面拍一次板。
|
|
269
|
+
这是「人是作者」这条红线在自动驾驶下的落点:可以自动化流程,不能自动化拍板。
|
|
270
|
+
|
|
271
|
+
边界(都写成了断言,不靠自觉):
|
|
272
|
+
|
|
273
|
+
- **只对主 agent**:委派深度 > 0 一律跳过,否则子 agent 会各自再问一遍(delegationDepthOf 同款规则)。
|
|
274
|
+
- **只对论文工作区**:indThesisRoot 找不到台账就完全不介入,别的项目里装了也不受打扰。
|
|
275
|
+
- **只问一次**:同一个 agent 只问一次;已有 意图规格.md 的会话只记一条日志、不重复打扰。
|
|
276
|
+
- **宿主缺服务就静默退化**:没有 userQuestions / goals 的组合同样能跑,只是退回单轮。
|
|
277
|
+
- **可关**:utopilot: { enabled: false } 退回「纯工具 + 技能」模式。
|
|
278
|
+
|
|
279
|
+
代价:这是一次**给人的表面的破坏性变更**(命令全没了)。21 个工具名一字未动,
|
|
280
|
+
所以模型侧与自动化不受影响;版本如实走 2.0.0。
|
|
281
|
+
|
|
282
|
+
之前的中间形态(一条 /thesis + 九个动词)在这个版本里被整体替换:它解决了「列表太吵」,
|
|
283
|
+
但没解决「人不该操作命令行」。留在这里作为教训:**先问清人要的是入口还是自动化**。
|
|
294
284
|
---
|
|
295
285
|
|
|
296
286
|
## 7. 数据与产物
|
|
@@ -336,14 +326,19 @@ DSH 的 profile 预检(`dsh-app-boot` 的 `evaluatePluginCompatibility`,在
|
|
|
336
326
|
|
|
337
327
|
| 层 | 命令 | 内容 |
|
|
338
328
|
|---|---|---|
|
|
339
|
-
| 纯逻辑与契约 | `npm run test:sandbox` |
|
|
329
|
+
| 纯逻辑与契约 | `npm run test:sandbox` | 422 条:相似度、归一化、处方、问题排序、状态机、幻灯渲染、OOXML/PDF 解析、记忆 SQL、代码结构摘要;装配契约(21 工具 / **0 条命令** / 2 服务 / 5 类监听);自动驾驶的四种「不该介入」与关卡拍板;`definePaperTool` 的 DSL→JSON Schema 编译 |
|
|
340
330
|
| **真实场景端到端** | `npm run test:e2e` | 65 条断言,见 §9.1 |
|
|
341
|
-
| **真实宿主** | `npm run test:host` |
|
|
331
|
+
| **真实宿主** | `npm run test:host` | 23 项:真实 cordis + dsh-tools 装配、工具 schema 被真实注册表接受、真实执行工具、宿主拒绝缺参、**闸门在真实 waterfall 上真的注入**、卸载后工具注销 |
|
|
342
332
|
| **真实引擎装载** | `npm run test:host-load` | 13 项:用宿主自己的预检函数判 manifest(本仓库 + 已安装副本)会不会被停用,再用真实 `dsh` 引擎 `--dump-config` 组合 profile 并校验 `Config`;`DSH_HOME` 指向工作区内临时目录,无需放宽权限 |
|
|
343
333
|
| 对外表面审计 | `npm run audit` | 工具/命令/技能契约一致 + 技能命名/BOM 检查,见 §9.3 |
|
|
334
|
+
| 脚本类型检查 | `npm run typecheck:scripts` | `scripts/**` 全部是 `.ts`,用 `tsconfig.scripts.json` 单独检查(`strict: false`:它们是从 JS 迁过来的构建脚本,只求抓错不追求类型完备)|
|
|
344
335
|
| 真实网络(可选) | `npm run test:net` | 真实学术 API 检索 → 收录 → 笔记 |
|
|
345
336
|
|
|
346
|
-
`npm run verify` = build + typecheck
|
|
337
|
+
`npm run verify` = build + typecheck(src 与 scripts)+ 单元/契约 + 审计 + 端到端,是主线不变的守门命令。
|
|
338
|
+
|
|
339
|
+
**全部源码与工具链都是 `.ts`**:`src/` 由 `tsc` 编译成 `lib/`(发布产物,`.gitignore` 里),`scripts/`、`tests/`
|
|
340
|
+
由 Node 24 直接执行(type stripping,不需要 ts-node 之类的加载器)。代价是**跑脚本的工具链 Node 需要 ≥ 22.18**,
|
|
341
|
+
而装机运行时不要求(它读 `lib/` 里的 JS)。
|
|
347
342
|
|
|
348
343
|
### 9.1 真实场景端到端基准
|
|
349
344
|
|
|
@@ -374,7 +369,7 @@ DSH 的 profile 预检(`dsh-app-boot` 的 `evaluatePluginCompatibility`,在
|
|
|
374
369
|
|
|
375
370
|
对外名字(工具名、命令名、技能名)是**契约**:学生与宿主都按名字调用,改名而不改文档
|
|
376
371
|
就是文档骗人,改名而不改测试就是契约失守。这类漂移只靠人工看必然漏,
|
|
377
|
-
故 `scripts/audit-surface.
|
|
372
|
+
故 `scripts/audit-surface.ts` 把它们固定成断言:**注册集必须恰好等于契约集**,
|
|
378
373
|
多一个少一个都失败;技能 frontmatter 的 `name` 必须等于目录名(DSH 按目录名发现技能);
|
|
379
374
|
`SKILL.md` 不得带 BOM(带 BOM 时宿主解析 frontmatter 返回 undefined,**整个技能被静默忽略**——
|
|
380
375
|
文件明明在、技能却不存在,是最难排查的一类故障)。
|
|
@@ -397,7 +392,7 @@ DSH 的 profile 预检(`dsh-app-boot` 的 `evaluatePluginCompatibility`,在
|
|
|
397
392
|
5. **代码演练内置语言矩阵只覆盖 Go/TS/Python/Rust**,其余语言需在配置里补 `gates`。
|
|
398
393
|
6. **子进程不可取消**:pandoc/marp/git 走 `spawnSync`,有超时上限,但 `exec.signal` 不进入子进程。
|
|
399
394
|
7. **受限环境下管道 stdio 被拒**:某些沙箱里 `stdio: 'pipe'` 会 `EPERM`,故默认 `stdio: 'ignore'`。
|
|
400
|
-
8. **宿主契约以本地 shim 声明**:真实签名核对见 [
|
|
395
|
+
8. **宿主契约以本地 shim 声明**:真实签名核对见 [host-api.md](./host-api.md),
|
|
401
396
|
运行时行为由端到端基准与真实宿主冒烟兜底。
|
|
402
397
|
9. **真实 `dsh` 引擎的装载验证需要写 `$DSH_HOME/profiles/<name>/cordis.yml`**(引擎在
|
|
403
398
|
`--dump-config` 前就会写它)。受限沙箱下该写入会被拒,`npm run test:host-load` 因此需要放宽文件权限;
|