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/docs/host-api.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# DSH 第三方插件宿主 API
|
|
1
|
+
# DSH 第三方插件宿主 API 参考
|
|
2
2
|
|
|
3
3
|
> **版本与兼容**:本文的签名摘自已安装产物,最初对着 **dsh 0.1.5-rc.1** 记录;
|
|
4
4
|
> 已用 **dsh 0.2.0-rc.2** 重新核对本插件实际用到的每一处(`defineTool` 的 DSL、
|
|
5
5
|
> `ctx.tools.register`、`agent/pre-step` 与 `tools/pre-execute` 的 waterfall、
|
|
6
|
-
> `ctx.
|
|
7
|
-
> `ctx.
|
|
6
|
+
> `ctx.skills.registerProvider`、`ctx.shell` / `ctx.sandboxPolicy`,以及自动驾驶用到的
|
|
7
|
+
> `ctx.userQuestions` / `ctx.goals` / 委派深度,见 §6.4),结论是契约未变。
|
|
8
8
|
> **唯一真正会挡住装载的不是 API,而是 manifest 的 peer range**——见 §7.7。
|
|
9
9
|
|
|
10
10
|
只记录契约:签名、类型、事件名、注册与加载规则。签名逐字摘自已安装产物的 `lib/types/**/*.d.ts` 与 `lib/*.js`,
|
|
@@ -290,6 +290,9 @@ class FsError extends HarnessError { readonly code: FsErrorCode; constructor(mes
|
|
|
290
290
|
|
|
291
291
|
## 4. 人类斜杠命令:`@deepseek-ai/dsh-commands`
|
|
292
292
|
|
|
293
|
+
> **本插件不用这一节**:dsh-thesis 2.x 一条斜杠命令都不注册(入口是 §6.4 的自动驾驶)。
|
|
294
|
+
> 保留这一节是因为宿主契约本身没变,别的插件可能用得上。
|
|
295
|
+
|
|
293
296
|
```ts
|
|
294
297
|
ctx.commands.register(definition: CommandDefinition): () => void
|
|
295
298
|
|
|
@@ -433,7 +436,14 @@ type PreStepDecision = { kind: 'reject' } | { kind: 'enter'; messages: UserMessa
|
|
|
433
436
|
|
|
434
437
|
`next()` 保持当前 messages;返回值替换进入该步骤的消息,或拒绝该步骤(mode `waterfall`,按 agent 作用域过滤派发)。
|
|
435
438
|
注入物必须是 `UserMessage`:`{ id, role: 'user', content: ContentBlock[], source }`,`source` 用
|
|
436
|
-
`{ kind: 'plugin
|
|
439
|
+
`{ kind: 'plugin:<name>' } & ContextFormed`(`form: 'instructions' | 'catalog' | 'snapshot' | 'notice' | 'relay' | 'recall'`)。
|
|
440
|
+
|
|
441
|
+
> **`kind` 必须是生产者自有值。** 从 v4 会话格式起,共享兜底 kind `plugin` 会被直接拒写:
|
|
442
|
+
> `format v4 message requires a producer-owned source kind`,而且是在落会话日志时抛,
|
|
443
|
+
> 整条会话起不来。第三方插件的规范写法是 `plugin:<包名>`——宿主的 v3→v4 迁移器
|
|
444
|
+
> (`@deepseek-ai/dsh-session-format-v3-to-v4` 的 `producerKind`)给未知生产者生成的就是它,
|
|
445
|
+
> 这样旧会话迁移后与新消息同源同 kind。本插件踩过:2.0.1 用了 `kind: 'plugin'`,
|
|
446
|
+
> 论文工作区里的新会话一开就报上面那句。
|
|
437
447
|
`form` 决定客户端怎么渲染,且**每个形态只带自己那几个字段**(`ContextFormed` 是判别联合):
|
|
438
448
|
`sections` 只属于 `snapshot`,`summary` 只属于 `notice`,`instructions` 的渲染依据是
|
|
439
449
|
`changes`(工作区指令文件的改动清单,见 `dsh-agent-instructions`)。
|
|
@@ -456,7 +466,7 @@ export function registerPreStep(ctx: Context, buildCard: (cwd: string) => Promis
|
|
|
456
466
|
kind: 'enter',
|
|
457
467
|
messages: [...decision.messages, {
|
|
458
468
|
id: randomUUID(), role: 'user', content: [{ type: 'text', text: note }],
|
|
459
|
-
source: { kind: 'plugin
|
|
469
|
+
source: { kind: 'plugin:my-plugin', form: 'snapshot', sections: [{ name: 'my-plugin', text: note }] },
|
|
460
470
|
}],
|
|
461
471
|
}
|
|
462
472
|
}, { prepend: true })
|
|
@@ -525,6 +535,39 @@ type PostToolDecision =
|
|
|
525
535
|
`user/message`、`system/message`、`assistant/message`、`assistant/attempt`、`tool/call`、`tool/result`。
|
|
526
536
|
所有带 `this: Scoped<Agent>` / `Scoped<ToolRuntime>` 的事件都按 agent 作用域过滤派发。
|
|
527
537
|
|
|
538
|
+
### 6.4 自动驾驶用到的四处契约(`thesis 2.x`)
|
|
539
|
+
|
|
540
|
+
插件不再注册命令,改为在 `agent/pre-step` 上主动把流程推起来。它依赖下面四处能力,
|
|
541
|
+
**每一处都是可选的**(缺失即降级,不抛错):
|
|
542
|
+
|
|
543
|
+
```ts
|
|
544
|
+
// 1) pre-step 的 payload 带 agent 本身(不只是 messages)
|
|
545
|
+
'agent/pre-step'(payload: { agent: Agent; messages: UserMessage[]; turn: number; step: number; signal: AbortSignal }): ...
|
|
546
|
+
|
|
547
|
+
// 2) 问人:结构化选项 + 结构化答案;不需要 tool call id
|
|
548
|
+
ctx.userQuestions.ask({ questions: AskUserQuestionItem[], agent?: Agent, signal?: AbortSignal })
|
|
549
|
+
: Promise<{ answers: { id: string; selected: string[]; custom?: string }[] }>
|
|
550
|
+
interface AskUserQuestionItem { id: string; question: string; header?: string; detail?: string
|
|
551
|
+
options?: { label: string; description?: string }[]; multiSelect?: boolean }
|
|
552
|
+
|
|
553
|
+
// 3) 建目标:宿主的目标轮驱动器(`dsh-goal-round-driver`)会渲染续跑提示并调 agent.followup()
|
|
554
|
+
ctx.goals.create(agent: Agent, request: { objective: string; maxGoalRounds?: number }): GoalView
|
|
555
|
+
|
|
556
|
+
// 4) 委派深度:子 agent 的会话头里 subagentDepth > 0,据此只对主 agent 生效
|
|
557
|
+
delegationDepthOf(agent) = max(agent.session.header.subagentDepth ?? 0, agent.options.subagentDepth ?? 0)
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
两条实测结论:
|
|
561
|
+
|
|
562
|
+
- `ctx.userQuestions.ask` 的 **answerer 是 UI 侧的 waterfall**(`user-questions/request`)。
|
|
563
|
+
传了 `agent` 时它只接受**活的 runtime root**(`CALLER_NOT_LIVE` / `DELEGATED_CALLER` / `NO_PROVIDER`
|
|
564
|
+
都是可能结果),所以插件把「问不到答案」当作正常退化,而不是错误。
|
|
565
|
+
- `askTimed(request, callId, timeoutMs)` 需要**工具调用 id**,插件侧拿不到;因此插件只用 `ask`,
|
|
566
|
+
并接受「用户不答就挂住这一轮、按停止键即取消」的行为。
|
|
567
|
+
|
|
568
|
+
未在真实 agent 会话里验证过的一点:**没有 tool call 承载的问题卡片能否被 Web UI 渲染**。
|
|
569
|
+
若不能,日志会写 `意图选择题没有拿到答案`,插件退化为单轮,不阻塞对话。
|
|
570
|
+
|
|
528
571
|
---
|
|
529
572
|
|
|
530
573
|
## 7. CLI:`@deepseek-ai/dsh`(profile 与插件安装)
|
|
@@ -669,7 +712,7 @@ for (const [name, range] of Object.entries(manifest.peerDependencies ?? {})) {
|
|
|
669
712
|
但正解是修 range。
|
|
670
713
|
- **这条门不执行插件代码,也不跑 `--dump-config`**:`--dump-config` 只组合配置树,
|
|
671
714
|
旧 range 也能组合成功。要观察它必须真的启动一次,或者直接用上面的函数判定
|
|
672
|
-
(本仓库的 `scripts/lib/host-compat.
|
|
715
|
+
(本仓库的 `scripts/lib/host-compat.ts` 就是这么做的,`npm run test:host-load`
|
|
673
716
|
会同时检查**本仓库 manifest** 与 **profile 里已安装的那一份**)。
|
|
674
717
|
|
|
675
718
|
---
|
package/docs/release.md
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# 发布
|
|
2
|
+
|
|
3
|
+
发版由 GitHub Actions 完成([`.github/workflows/publish.yml`](../.github/workflows/publish.yml))。
|
|
4
|
+
**打 tag 即发布**,本地不需要 `npm login`,也不需要任何 npm token。
|
|
5
|
+
|
|
6
|
+
认证走 **Trusted Publishing(OIDC 可信发布)**:npm 只接受「这个仓库的这个 workflow」发来的包,
|
|
7
|
+
凭据是每次运行临时签发的,不落盘、不过期、也没有 2FA 输 OTP 的问题;provenance 由 npm 自动附上。
|
|
8
|
+
|
|
9
|
+
## 一次性设置(只做一次)
|
|
10
|
+
|
|
11
|
+
1. 打开 <https://www.npmjs.com/package/dsh-thesis/access> → **Trusted Publishers** →
|
|
12
|
+
**Select publisher: GitHub Actions**,填四个字段:
|
|
13
|
+
|
|
14
|
+
| 字段 | 填什么 |
|
|
15
|
+
|---|---|
|
|
16
|
+
| Organization or user | `booondenz` |
|
|
17
|
+
| Repository | `dsh-thesis` |
|
|
18
|
+
| Workflow filename | `publish.yml`(只写文件名,不带路径)|
|
|
19
|
+
| Environment name | **留空**(除非 workflow 里写了 `environment:`)|
|
|
20
|
+
|
|
21
|
+
同一页下方的 **Allowed actions**:
|
|
22
|
+
|
|
23
|
+
| 选项 | 勾不勾 | 为什么 |
|
|
24
|
+
|---|---|---|
|
|
25
|
+
| stage publish | 强制,改不了 | — |
|
|
26
|
+
| **Allow npm publish** | **勾上** | 不勾的话 `npm publish` 会被拒(`403 OIDC permission denied for this action`),只接受 `npm stage publish`,每次发版还得你到网页上做 2FA 批准 |
|
|
27
|
+
| Allow npm dist-tag | 不用勾 | `npm publish` 会自动把 `latest` 指过去;我们没有 `npm dist-tag` 操作 |
|
|
28
|
+
|
|
29
|
+
> 黄色提示条只说「provider 与必填字段建好后不能改」,`Allowed actions` 的两个勾选框随时可以改。
|
|
30
|
+
|
|
31
|
+
2. 确认仓库是 **public**:私有仓库发不出 provenance。
|
|
32
|
+
3. 不需要 `NPM_TOKEN`,**之前建过的话建议在 Settings → Secrets 里删掉**,免得以后误用。
|
|
33
|
+
|
|
34
|
+
> 配置要先「验证」过一次才算生效:2026-10 起,长期没成功发布过的可信发布配置会自动过期。
|
|
35
|
+
> 所以配完就立刻发一次版。
|
|
36
|
+
|
|
37
|
+
## 备选:用 token(不推荐)
|
|
38
|
+
|
|
39
|
+
如果哪天可信发布不可用,也可以在 npm 建 **Classic → Automation** 类型的 token
|
|
40
|
+
(Granular token 在开了 2FA 的账号上会报 `EOTP`,除非它明确允许绕过 2FA),
|
|
41
|
+
存成仓库 secret `NPM_TOKEN`,然后在 workflow 的 publish 步骤加回:
|
|
42
|
+
|
|
43
|
+
```yaml
|
|
44
|
+
env:
|
|
45
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
并把 `setup-node` 的 `with:` 里加回 `registry-url: https://registry.npmjs.org`。
|
|
49
|
+
Automation token 专为 CI 设计,不受 2FA 影响。
|
|
50
|
+
|
|
51
|
+
## 发一次版
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npm version patch --no-git-tag-version # 或 minor / major,或手动改 package.json
|
|
55
|
+
git add package.json package-lock.json
|
|
56
|
+
git commit -m "chore: release v2.0.1"
|
|
57
|
+
git tag v2.0.1
|
|
58
|
+
git push origin main --tags
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Action 会依次做:
|
|
62
|
+
|
|
63
|
+
| 步骤 | 失败就停 |
|
|
64
|
+
|---|---|
|
|
65
|
+
| `npm ci` | 锁文件与 package.json 不同步会在这里红 |
|
|
66
|
+
| tag 与 `package.json` 版本一致 | 防止「tag 写 v2.0.1、包里是 2.0.0」|
|
|
67
|
+
| 该版本是否已存在于 npm | 已存在则**跳过发布**(不会红,也不会覆盖)|
|
|
68
|
+
| `npm pack --dry-run` | 发布内容一目了然(日志里能看到文件清单)|
|
|
69
|
+
| `npm publish` | 内部触发 `prepublishOnly` 守卫:构建 + 类型 + 单测 + 审计 + 端到端;provenance 由可信发布自动附带 |
|
|
70
|
+
| 建 GitHub Release | 标题用 tag,正文自动生成 |
|
|
71
|
+
|
|
72
|
+
发布成功后 npm 页面会带一个 **Provenance** 徽章,点进去能看到是哪次 commit、哪次 workflow 构建的。
|
|
73
|
+
|
|
74
|
+
## 在网页上发版(完全不碰命令行)
|
|
75
|
+
|
|
76
|
+
1. 打开 <https://github.com/booondenz/dsh-thesis/releases/new>;
|
|
77
|
+
2. **Choose a tag** 里输入 `v2.0.1`,点下拉第一条 **Create new tag: v2.0.1 on publish**;
|
|
78
|
+
3. **Target** 选 `main`,并确认它指向 bump 版本的那个 commit(否则 tag 会打在别的提交上,
|
|
79
|
+
workflow 第一步的版本比对就会红);
|
|
80
|
+
4. 标题写 `v2.0.1`,正文可以留空——workflow 里是 `gh release view || gh release create`,
|
|
81
|
+
发现 Release 已存在会跳过;
|
|
82
|
+
5. **Publish release**。
|
|
83
|
+
|
|
84
|
+
创建 tag 本身就是一次 `push`,所以 `publish.yml` 会被触发。两条路等价:也可以先
|
|
85
|
+
`git push origin v2.0.1` 再建 Release,或者只推 tag 不建 Release(workflow 会替你建)。
|
|
86
|
+
|
|
87
|
+
## 确认发成功了
|
|
88
|
+
|
|
89
|
+
| 看哪 | 期望 |
|
|
90
|
+
|---|---|
|
|
91
|
+
| Actions → **publish** | 这次 run 是绿的;Summary 里有一行 `https://www.npmjs.com/package/dsh-thesis/v/2.0.1` |
|
|
92
|
+
| `npm view dsh-thesis version` | `2.0.1`(registry 立刻生效,网页可能还要一分钟)|
|
|
93
|
+
| `npm view dsh-thesis dist-tags` | `{ latest: '2.0.1' }` |
|
|
94
|
+
| <https://www.npmjs.com/package/dsh-thesis> | 版本号旁出现 **Provenance** 徽章 |
|
|
95
|
+
| 仓库 **Releases** | 多了一条 `v2.0.1` |
|
|
96
|
+
|
|
97
|
+
Actions 里**根本没出现 publish 这个 run**,说明 tag 没推上去(或名字不是 `v` 开头);
|
|
98
|
+
出现 run 但红在第一步,通常是 tag 与 `package.json` 版本对不上。
|
|
99
|
+
|
|
100
|
+
## 发完之后:让 DSH 用上新版
|
|
101
|
+
|
|
102
|
+
profile 把版本钉在 `~/.dsh/profiles/<profile>/package.json` 里(例如 `"dsh-thesis": "1.0.1"`),
|
|
103
|
+
所以 npm 上发了新版**不会自动生效**。到插件管理器里移除再装一次(会取 `latest`),或者把那条依赖
|
|
104
|
+
改成 `"^2.0.1"` 后重装,然后**重启 DSH**——2.0 删掉了全部斜杠命令,不是热更新能覆盖的。
|
|
105
|
+
|
|
106
|
+
## 手动触发
|
|
107
|
+
|
|
108
|
+
Actions → publish → Run workflow:只做打包预览,**不会发布**。用来确认「这次发出去的包里到底有什么」。
|
|
109
|
+
想真发版,还是打 tag。
|
|
110
|
+
|
|
111
|
+
## 失败排查
|
|
112
|
+
|
|
113
|
+
| 现象 | 原因 |
|
|
114
|
+
|---|---|
|
|
115
|
+
| `EOTP` / `This operation requires a one-time password` | 用的是需要 OTP 的 token(2FA 账号的 Granular / Publish token)。CI 里没人能输 OTP:改用可信发布,或换 Classic → Automation token |
|
|
116
|
+
| 发布被拒,提示只能 `npm stage publish` | 可信发布里没勾 **Allow publish directly**(默认只允许 stage)|
|
|
117
|
+
| `403 … OIDC permission denied for this action` | 同一条:OIDC 认证已经通过(组织/仓库/workflow 名字都对),只是没给「直接发布」权限。去包设置里编辑那条配置,勾上 **Allow npm publish** |
|
|
118
|
+
| `401 Unauthorized` | token 过期(Automation token 有 90/180 天寿命),或可信发布配置里 workflow 文件名写错 |
|
|
119
|
+
| `npm ci … not in sync` | 改了 `package.json` 的依赖/peer 却没跑 `npm install --package-lock-only` |
|
|
120
|
+
| `403 … cannot publish over previously published version` | 版本号没升;这条在 workflow 里已被「已存在则跳过」挡住,手动发版时要注意 |
|
|
121
|
+
| 守卫里 `单元/契约测试` 红 | 本地 `npm test` 先复现;守卫跑的就是它 |
|
|
122
|
+
| 守卫警告「未找到 DSH 安装」 | CI 里正常(没有宿主);**发版前请在本地跑一次 `npm run test:host-load` 与 `npm run test:host`** |
|
|
123
|
+
|
|
124
|
+
## 撤回与补救
|
|
125
|
+
|
|
126
|
+
- **已发布的版本不能改**,只能 `npm deprecate dsh-thesis@2.0.1 "原因与替代版本"`。
|
|
127
|
+
- 72 小时内理论上可以 `npm unpublish`,但那会让依赖它的人突然装不上,**不要用**。
|
|
128
|
+
- 发错了就立刻发一个 patch:`2.0.2`。
|
|
129
|
+
|
|
130
|
+
## 仍然可以本地发布
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
npm login
|
|
134
|
+
npm publish --access public # 会跑同一个 prepublishOnly 守卫,会交互式要 OTP
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
本地发布用的是你登录后的凭据(可以输 OTP),不需要 token,也不需要可信发布配置。
|
|
138
|
+
CI 只是把「构建 → 校验 → 发布」串起来,判据完全一样。
|
package/docs/tools.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# 工具与技能
|
|
2
|
+
|
|
3
|
+
工具名、命令面、技能名都是**对外契约**:改名就是破坏性变更。`npm run audit` 会把这三样
|
|
4
|
+
都核对一遍(21 个工具 / 0 条斜杠命令 / 11 个技能 + 命名与 BOM 检查)。
|
|
5
|
+
|
|
6
|
+
## 命名空间
|
|
7
|
+
|
|
8
|
+
| 前缀 | 管什么 |
|
|
9
|
+
|---|---|
|
|
10
|
+
| `thesis_*` | 论文工作区里的东西(材料、要求、章节、检查、构建、答辩素材、幻灯) |
|
|
11
|
+
| `defense_code_*` | 答辩层的代码演练(把系统拆成讲得清的模块) |
|
|
12
|
+
| `fact_*` | 跨会话事实(学校规范、导师要求、写作偏好) |
|
|
13
|
+
|
|
14
|
+
## `thesis_*`(15 个)
|
|
15
|
+
|
|
16
|
+
| 工具 | 一句话 | 关键约束 |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| `thesis_ingest` | 把材料读成文本与结构摘要 | docx/xlsx/pptx/pdf/md/csv/bib + 源码目录;源码只给结构,不贴正文;已存在的摘要不覆盖 |
|
|
19
|
+
| `thesis_intake` | 一次问一个要求问题,问成《意图规格》 | 必答项不齐拒绝 `done`;材料里能读出来的不重复问 |
|
|
20
|
+
| `thesis_init` | 建论文工作区 | 空目录才能建;九阶段目录 + 台账 + 七章模板 + 技能包 + git |
|
|
21
|
+
| `thesis_progress` | 看进度 / 过 G1-G4 | 关卡是**拒绝**不是提醒;关联任务未完成不许过关 |
|
|
22
|
+
| `thesis_decide` | 记一条关键决定 | 内容/理由/备选三段,写进决定日志 |
|
|
23
|
+
| `thesis_lit_search` | 真实检索文献 | Semantic Scholar → DBLP → arXiv → Crossref 降级;写检索缓存与审计记录 |
|
|
24
|
+
| `thesis_lit_save` | 收录进 `refs.bib` | **只接受检索缓存里的 id**(零假文献的落点);DOI 重复自动跳过 |
|
|
25
|
+
| `thesis_lit_note` | 生成阅读笔记骨架 | 五节模板;已存在不覆盖 |
|
|
26
|
+
| `thesis_review` | 单章六项评审 | 字数区间 / 大纲小节 / 引用编号 / 图表编号 / 未完成标记 / G2 清单 |
|
|
27
|
+
| `thesis_check` | 全文五项检查 | 引用双向一致、字数、图表编号、术语定义顺序、学校模板探测 |
|
|
28
|
+
| `thesis_stylecheck` | 六条 AI 味启发式 | 模板套话、空洞结论、自我暴露、翻译腔、句式单一、无锚点长段落 |
|
|
29
|
+
| `thesis_build` | 出 `论文.docx` | 有 pandoc 用 pandoc + 学校模板,没有用内置零依赖生成器(显式标注) |
|
|
30
|
+
| `thesis_originality` | 本地降重度量 | scan / verify / report;**不接收费查重**,报告里是本地估算 |
|
|
31
|
+
| `thesis_defense` | 答辩素材 + 六类问题库 | 每个问题带证据锚点(哪个文件哪一行) |
|
|
32
|
+
| `thesis_slides` | 答辩幻灯 | Marp 兼容 Markdown;outline / convert / check / guide;pptx 依赖外部引擎 |
|
|
33
|
+
|
|
34
|
+
## `defense_code_*`(3 个)
|
|
35
|
+
|
|
36
|
+
| 工具 | 一句话 |
|
|
37
|
+
|---|---|
|
|
38
|
+
| `defense_code_status` | 我的系统我讲得清吗(阶段、里程碑、验证门、未过的问题) |
|
|
39
|
+
| `defense_code_next` | 下一个该弄懂的模块(todo + 评分要点) |
|
|
40
|
+
| `defense_code_update` | 登记 / 推进 / 评分 / 重试(每次改动立即落盘) |
|
|
41
|
+
|
|
42
|
+
语言矩阵内置 Go / TS / Python / Rust;其它语言在配置里补 `codeWalkthrough.gates`。
|
|
43
|
+
|
|
44
|
+
## `fact_*`(3 个)
|
|
45
|
+
|
|
46
|
+
| 工具 | 一句话 |
|
|
47
|
+
|---|---|
|
|
48
|
+
| `fact_search` | 上次记下的学校规范还在吗(key/value 子串检索) |
|
|
49
|
+
| `fact_remember` | 记住一条跨会话仍成立的稳定事实 |
|
|
50
|
+
| `fact_context` | 把这个课题已知的稳定事实一次性拉回来 |
|
|
51
|
+
|
|
52
|
+
只记**跨会话仍然成立**的东西(学校规范、导师偏好、课题稳定事实);进度、临时任务、一次性
|
|
53
|
+
实验数字不进记忆,那些在台账与实验记录里。
|
|
54
|
+
|
|
55
|
+
## 技能(11 个)
|
|
56
|
+
|
|
57
|
+
随插件发布,`thesis_init` 把它们复制进论文仓库 `.dsh/skills/`,跟着论文一起 git 版本化。
|
|
58
|
+
|
|
59
|
+
| 技能 | 解决什么 |
|
|
60
|
+
|---|---|
|
|
61
|
+
| `thesis-pipeline` | 全流程总纲:阶段、关卡、工具地图、会话入口顺序 |
|
|
62
|
+
| `thesis-opener` | 选题与开题(课题怎么定、开题报告怎么写) |
|
|
63
|
+
| `thesis-literature` | 文献调研:检索策略、阅读笔记、综述组织 |
|
|
64
|
+
| `thesis-eng-design` | 需求 / 设计 / 选型论证的写法 |
|
|
65
|
+
| `thesis-writing` | 逐章写作规范与验收标准 |
|
|
66
|
+
| `thesis-citation` | GB/T 7714 引用格式(只解决「格式对不对」) |
|
|
67
|
+
| `thesis-defense` | 答辩素材、问题库、幻灯与讲稿 |
|
|
68
|
+
| `code-walkthrough` | 把系统拆成答辩讲得清的模块(配 `defense_code_*`) |
|
|
69
|
+
| `paper-intake` | 材料到手后的追问方法论(怎么问出可证伪的要求) |
|
|
70
|
+
| `paper-dedup` | 原创性与降重:本地度量、改写处方、复测 |
|
|
71
|
+
| `thesis-inquiry` | 写作要求被质疑、导师口径模糊时怎么问清 |
|
|
72
|
+
|
|
73
|
+
## 没有斜杠命令
|
|
74
|
+
|
|
75
|
+
`ctx.commands` 一次都不注册。入口是自动驾驶([autopilot.md](./autopilot.md)),
|
|
76
|
+
或者直接跟模型说话让它调工具。
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# 排查
|
|
2
|
+
|
|
3
|
+
## 装了但没反应 / 工具看不见
|
|
4
|
+
|
|
5
|
+
宿主在装载前会校验 `package.json` 里 `@deepseek-ai/dsh*` 的 `peerDependencies`,
|
|
6
|
+
**不满足就把这一行静默 `disabled`**(stderr 只有一句 `dsh: disabling profile plugin row …`)。
|
|
7
|
+
本插件声明:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
@deepseek-ai/dsh-tools: >=0.2.0-rc.2 <0.3.0-0
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
排查顺序:
|
|
14
|
+
|
|
15
|
+
1. 确认 dsh 版本:`dsh --version`。跨小版本(0.3+)时这条 range 就要放宽,不能硬装。
|
|
16
|
+
2. 跑 `npm run test:host-load`:它用**宿主自己的预检函数**判断真实副本会不会被停用。
|
|
17
|
+
3. 跑 `npm run test:host`:真实 cordis 装配 + 真实工具注册表。
|
|
18
|
+
4. 装了插件管理器却报 `installation rejected`:多半是旧版本缓存。`dsh plugin add dsh-thesis@<确切版本>` 钉住版本,
|
|
19
|
+
或 `pnpm cache delete dsh-thesis` 后再装。
|
|
20
|
+
|
|
21
|
+
## 重启后还是旧行为
|
|
22
|
+
|
|
23
|
+
- `dsh plugin add` 装的是 **npm 上的那一版**,改了源码不重装不会生效;本地开发用
|
|
24
|
+
`node scripts/install-into-profile.ts --profile web`(把 profile 指到本仓库,重启生效)。
|
|
25
|
+
- DSH 没有 TS 加载器:**必须先 `npm run build`**(产出 `lib/`),直接指向源码不会工作。
|
|
26
|
+
- 确认改到的是同一个 profile:`--profile web` 要和实际启动参数一致。
|
|
27
|
+
|
|
28
|
+
## 说了话但没弹那道选择题
|
|
29
|
+
|
|
30
|
+
自动驾驶只在「**论文工作区** + **主 agent** + **还没有意图规格**」时问。看会话日志:
|
|
31
|
+
|
|
32
|
+
| 日志 | 含义 |
|
|
33
|
+
|---|---|
|
|
34
|
+
| `已有意图规格` | `00-管理/意图规格.md` 已存在,不再重复问(删掉它或换工作区可重新选)|
|
|
35
|
+
| `意图选择题没有拿到答案` | UI 不接受非工具调用的问题卡片,或你取消了 |
|
|
36
|
+
| `宿主没有 userQuestions 服务` | 这套组合没有问答面 |
|
|
37
|
+
| `宿主没有 goals 服务` | 只会跑一轮,不自动续轮 |
|
|
38
|
+
|
|
39
|
+
前三行都意味着:插件有意**不猜**你的意图。直接说话即可,工具都在。
|
|
40
|
+
|
|
41
|
+
## 关卡没问就过了
|
|
42
|
+
|
|
43
|
+
`autopilot.gateApproval` 被设成了 `false`。改成 `true` 就恢复「过人卡必须由人拍板」。
|
|
44
|
+
|
|
45
|
+
## PDF 读不出文字
|
|
46
|
+
|
|
47
|
+
扫描版(没有文本层)、加密 PDF、只有 CID 字体且无 ToUnicode 映射的 PDF 抽不出内容。
|
|
48
|
+
工具会**如实说明原因**,不会编造。处理办法:先用 OCR 或另存一份带文本层的 PDF 再摄取。
|
|
49
|
+
|
|
50
|
+
## `.pptx` 没生成
|
|
51
|
+
|
|
52
|
+
幻灯的真相是 Markdown(`07-答辩/PPT.md`),`.pptx` 交给外部工具:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npx -y @marp-team/marp-cli 07-答辩/PPT.md --pptx
|
|
56
|
+
# 或
|
|
57
|
+
pandoc 07-答辩/PPT.md -o 07-答辩/PPT.pptx
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
两者都没有时,`thesis_slides convert` 会写一份 `07-答辩/PPT转换说明.md`(探测结果 + 确切命令 + 退出码),
|
|
61
|
+
**绝不假装成功**。装了 marp 之后重跑即可。
|
|
62
|
+
|
|
63
|
+
## 旧格式打不开
|
|
64
|
+
|
|
65
|
+
`.doc` / `.xls` / `.ppt` 不支持,先另存为 `.docx` / `.xlsx` / `.pptx`。
|
|
66
|
+
|
|
67
|
+
## 工具写到别的目录去了?
|
|
68
|
+
|
|
69
|
+
不会,但会**报错**:配了 `workspace` 却找不到 `00-管理/进度台账.md` 时,工具直接失败而不是退回 cwd 探测。
|
|
70
|
+
这正是防「写错地方」的设计。要么改 `workspace`,要么先在工作区跑 `thesis_init`。
|
|
71
|
+
|
|
72
|
+
## 读文件失败 vs 文件不存在
|
|
73
|
+
|
|
74
|
+
两者严格区分:读失败(权限 / IO)会抛错并保持原文件不动,绝不会用默认值覆盖。
|
|
75
|
+
「读不出来 ≠ 不存在」是整个仓库的硬约束。
|
|
76
|
+
|
|
77
|
+
## 中文乱码
|
|
78
|
+
|
|
79
|
+
工作区里的文件统一 UTF-8(无 BOM)。Windows 上用 PowerShell 查看时加 `-Encoding utf8`:
|
|
80
|
+
|
|
81
|
+
```powershell
|
|
82
|
+
Get-Content 00-管理\进度台账.md -Encoding utf8
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## 代价与限速
|
|
86
|
+
|
|
87
|
+
- 自动续跑每一轮都是一次完整模型调用,`autopilot.maxGoalRounds` 是唯一刹车;调小它比事后心疼便宜。
|
|
88
|
+
- 外部命令(pandoc / marp / git)走 `spawnSync`:有超时,**没有信号传递**(按下停止不会杀掉子进程)。
|
package/docs/usage.md
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# 使用手册
|
|
2
|
+
|
|
3
|
+
> 只想知道怎么装:见 [README](../README.md)。这里讲**用起来是什么样**。
|
|
4
|
+
|
|
5
|
+
## 前置条件
|
|
6
|
+
|
|
7
|
+
- DSH 里装好 `dsh-thesis`,重启后可见 `thesis_*` / `fact_*` / `defense_code_*` 三组工具。
|
|
8
|
+
- **把会话开在论文目录里**最省事:多数工具从会话 cwd 向上探测 `00-管理/进度台账.md` 来定位工作区。
|
|
9
|
+
- 也可以显式指定:`config: { workspace: /path/to/你的论文 }`。配了它就**只认它**,路径写错会直接报错,
|
|
10
|
+
绝不会写到别的目录去。
|
|
11
|
+
|
|
12
|
+
工作区可以是空的(还没有论文),`thesis_init` 会把九阶段目录、台账、决定日志、七章模板和技能包一次性建好。
|
|
13
|
+
|
|
14
|
+
## 第一次会话
|
|
15
|
+
|
|
16
|
+
把材料丢进工作区(或告诉它绝对路径),说一句:
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
这是我的论文材料,帮我做毕业设计
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
插件接管后是这样走的:
|
|
23
|
+
|
|
24
|
+
1. **弹一道选择题**(只有一次):从零走到答辩 / 只补合规与答辩 / 只做答辩准备 / 先别自动跑。
|
|
25
|
+
细节见 [autopilot.md](./autopilot.md)。
|
|
26
|
+
2. 选定后建目标、自动一轮轮跑:材料摄取 → 逐题追问 → 文献 → 设计 → 实现 → 测试 → 论文 → 合规 → 答辩。
|
|
27
|
+
3. 只在 **G1-G4 人工关卡**停下来,让你在审批界面点「允许」或「拒绝」。
|
|
28
|
+
|
|
29
|
+
没有材料也能用:「我要做毕业设计,还没定题」→ 走选题工作坊,先定课题再进流水线。
|
|
30
|
+
|
|
31
|
+
## 九阶段与关卡
|
|
32
|
+
|
|
33
|
+
| 阶段 | 产出物 | 验收标准 | 人工关卡 |
|
|
34
|
+
|---|---|---|---|
|
|
35
|
+
| 1 选题 | 选题确认书 | 课题明确、工作量合理、答辩友好 | **G1** |
|
|
36
|
+
| 2 开题 | 开题报告 + 任务书 | 导师认可;结构与规范达标 | **G3** |
|
|
37
|
+
| 3 文献调研 | 文献库 + 笔记 + 综述素材 | 15-30 篇真实文献;每篇有笔记 | — |
|
|
38
|
+
| 4 系统设计 | 需求/设计/选型文档 | 方案可落地;选型有论证 | — |
|
|
39
|
+
| 5 系统实现 | 可运行系统 + git 提交 | 功能真实可跑 | — |
|
|
40
|
+
| 6 系统测试 | 测试报告 + 真实结果 | 结果可复现;零伪造 | — |
|
|
41
|
+
| 7 论文撰写 | 七章正文 | 逐章人工验收 | **G2**(每章一次) |
|
|
42
|
+
| 8 定稿与合规 | 论文.docx + 检查报告 | 格式/引用/自查全部通过 | **G4** |
|
|
43
|
+
| 9 答辩 | 幻灯 + 演练记录 | 能讲清设计与实现 | — |
|
|
44
|
+
|
|
45
|
+
关卡由 `thesis_progress` 在工具层强制:未过该阶段的入口关卡时,任务推进会被**拒绝**(不是提醒)。
|
|
46
|
+
|
|
47
|
+
## 材料与追问
|
|
48
|
+
|
|
49
|
+
- `thesis_ingest <绝对路径>`:docx / xlsx / pptx / pdf / md / csv / bib,以及源码目录(只给文件、行数、
|
|
50
|
+
声明与技术栈,**不贴源码正文**)。产出 `00-管理/材料清单.md` 与逐文件摘要;已存在的摘要绝不覆盖。
|
|
51
|
+
- `thesis_intake`:一次只问一个问题,每问都带「为什么问 / 影响哪个产出 / 合格答案形态」。
|
|
52
|
+
材料里能读出来的不重复问;必答项不齐时拒绝 `done`。答案落盘成 `00-管理/意图规格.md`(唯一真相)。
|
|
53
|
+
- 断点续问:状态在 `.paper/intake.json`(相对工作区根),换会话接着问,不重复。
|
|
54
|
+
|
|
55
|
+
## 常见动作
|
|
56
|
+
|
|
57
|
+
| 想做的事 | 怎么说 / 调什么 |
|
|
58
|
+
|---|---|
|
|
59
|
+
| 换学校模板 | 把模板放进 `06-论文/assets/学校模板/`,再跑 `thesis_check`(探测到就用,探测不到显式标注「非学校模板」)|
|
|
60
|
+
| 只改某一章 | 直接说「改第三章的方法部分」,改完 `thesis_review 03-设计` |
|
|
61
|
+
| 回填学校查重结果 | `thesis_originality action=report detected_rate=12 detected_system=知网` |
|
|
62
|
+
| 出 Word | `thesis_build`(有 pandoc 用 pandoc + 模板,没有就用内置零依赖生成器)|
|
|
63
|
+
| 只做答辩 | `thesis_defense` → `thesis_slides` → 代码演练 `defense_code_*` |
|
|
64
|
+
| 记住学校规范 | `fact_remember key=school.dedup.system value="知网,查重阈值 20%"` |
|
|
65
|
+
| 看进度 | `thesis_progress action=report` |
|
|
66
|
+
|
|
67
|
+
## 产出物
|
|
68
|
+
|
|
69
|
+
| 产物 | 位置 |
|
|
70
|
+
|---|---|
|
|
71
|
+
| 意图规格(唯一真相) | `00-管理/意图规格.md` |
|
|
72
|
+
| 材料清单 + 逐文件摘要 | `00-管理/材料清单.md`、`00-管理/材料/*.md` |
|
|
73
|
+
| 进度台账 / 决定日志 / 时间线 | `00-管理/` |
|
|
74
|
+
| 文献库与检索审计 | `02-文献/refs.bib`、`检索记录.md`、`笔记/` |
|
|
75
|
+
| 章节与 Word | `06-论文/章节/*.md`、`06-论文/产出/论文.docx` |
|
|
76
|
+
| 答辩素材 / 幻灯 / 问题库 | `07-答辩/` |
|
|
77
|
+
| 检查报告(引用 / 格式 / AI 味 / 降重) | `08-合规/` |
|
|
78
|
+
|
|
79
|
+
## 中断与续跑
|
|
80
|
+
|
|
81
|
+
会话断了不要紧:进度、决定、追问状态、检索缓存全在工作区文件里。重开一个会话说一句
|
|
82
|
+
「接着做」即可——`thesis_progress action=report` 会把当前阶段、未过的关卡与下一步报出来。
|
|
83
|
+
|
|
84
|
+
## 多条流水线同时进行
|
|
85
|
+
|
|
86
|
+
一个工作区 = 一个课题。不同课题就不同目录,各开各的会话;跨会话的稳定事实(学校规范、
|
|
87
|
+
导师偏好)走 `fact_*`,那是全局共享的。
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 自动驾驶:插件在后台把流程推起来,人只在两处出现——**开头选一次意图**、**过关卡时拍一次板**。
|
|
3
|
+
*
|
|
4
|
+
* 为什么不让人敲命令:命令是给人操作 CLI 的入口,而这里真正的主角是模型与流水线。
|
|
5
|
+
* 插件要做的不是再提供一套动词,而是:
|
|
6
|
+
*
|
|
7
|
+
* 1. `agent/pre-step`:认出「这是论文工作区、用户还没定过意图」→ 问一道选择题
|
|
8
|
+
* (`ctx.userQuestions.ask`,三四档常见起点)→ 把答案写进决定日志 →
|
|
9
|
+
* `ctx.goals.create` 建目标(宿主的 goal-round-driver 此后自动续轮)→
|
|
10
|
+
* 注入一条 operating contract(怎么推进、怎么并行、哪里必须停)。
|
|
11
|
+
* 2. `tools/pre-execute`:模型要过 G1-G4 时拦一次 `ask`,由人在审批界面拍板。
|
|
12
|
+
*
|
|
13
|
+
* 两条铁律:**只对主 agent 生效**(子 agent 委派深度 > 0 一律跳过)、
|
|
14
|
+
* **只对论文工作区生效**(找不到台账就完全不介入,别的项目里装了这个插件也不受干扰)。
|
|
15
|
+
*
|
|
16
|
+
* @module dsh-thesis/autopilot
|
|
17
|
+
*/
|
|
18
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
19
|
+
import type { AutopilotOptions } from '../config.ts';
|
|
20
|
+
import type { AutopilotAnswerItem, AutopilotAgent } from './types.ts';
|
|
21
|
+
/** 一个 agent 的委派深度:与宿主 `delegationDepthOf` 同一条规则(头里的深度只增不减)。 */
|
|
22
|
+
export declare function agentDepth(agent: AutopilotAgent): number;
|
|
23
|
+
/** 从结构化答案里取出被选中的标签(兼容多选与自定义输入)。 */
|
|
24
|
+
export declare function selectedLabel(answer: {
|
|
25
|
+
readonly answers?: readonly AutopilotAnswerItem[];
|
|
26
|
+
} | undefined): string | undefined;
|
|
27
|
+
/** 装配参数:配置里的自动驾驶块 + 意图规格落盘位置(与 intake 共用同一份配置)。 */
|
|
28
|
+
export interface AutopilotInstallOptions extends AutopilotOptions {
|
|
29
|
+
/** 意图规格文件相对论文工作区根的位置。 */
|
|
30
|
+
readonly specRel: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* 装上自动驾驶的两处监听。
|
|
34
|
+
*
|
|
35
|
+
* 顺序关键:`agent/pre-step` 先 `await next()` 再注入(与写作意图闸门同一约定),
|
|
36
|
+
* 任何异常都吞成「不介入」,绝不把错误抛进 agent 循环。
|
|
37
|
+
*/
|
|
38
|
+
export declare function installAutopilot(ctx: Context, options: AutopilotInstallOptions): void;
|