@yangdcm/dsh-expert-team 1.3.5 → 1.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +77 -0
- package/README.en.md +224 -135
- package/README.md +104 -38
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,83 @@
|
|
|
3
3
|
本包遵循[语义化版本](https://semver.org/lang/zh-CN/)。dsh 宿主版本线的对应关系写在
|
|
4
4
|
`package.json` 的 `engines.dsh` 与 `dsh.compatibility` 里,插件市场按它判断"这个插件跟你的宿主兼不兼容"。
|
|
5
5
|
|
|
6
|
+
## 1.3.7
|
|
7
|
+
|
|
8
|
+
**修掉 1.3.6 两张手绘矢量图的文字重叠,并让 npm 页面也能显示 README 图片。**
|
|
9
|
+
|
|
10
|
+
纯文档/资产版本 —— `lib/`、`client.js` **零改动**,无依赖变化,`files` 字段未动。
|
|
11
|
+
|
|
12
|
+
### 两张 SVG:改为**分带布局**(band layout)
|
|
13
|
+
|
|
14
|
+
上一版的问题不是"画得不好",而是**两条信息共用了同一 y 带**:
|
|
15
|
+
|
|
16
|
+
- `hero.svg`:指标行与副标题同带 ⇒ 大数字 `12` **压在副标题尾部**;副标题/页脚在深底上对比度偏低。
|
|
17
|
+
- `pipeline.svg`:「硬门」徽标与图例行同带 ⇒ 徽标**压住图例第三项**「同一阶段内并行扇出」,
|
|
18
|
+
「确认门」徽标也飘在图例那一行而不是它注记的方框上方。
|
|
19
|
+
|
|
20
|
+
改法:每张图先把垂直空间切成**互不重叠的带**,每个元素**只能落在自己的带内**,带范围写进文件注释便于后续修改。
|
|
21
|
+
|
|
22
|
+
- `hero.svg` 带表:B1 标题 `[44,84]` · B2 副标题 `[88,114]` · B3 命令框(左 x≤600)/ 指标(右 x≥636)`[118,178]`
|
|
23
|
+
· B4 进度条 `[190,210]` · B5 页脚 `[218,246]`。指标整体下移,数字与图注留 7px 净空;
|
|
24
|
+
副标题 `#94a3b8 → #c7d2fe`、页脚 `→ #a5b4fc`(深底对比度)。
|
|
25
|
+
- `pipeline.svg` 带表:B1 标题 `[30,60]` · B2 副标题 `[62,82]` · B3 图例 `[86,104]` · **B4 门徽标 `[110,136]`(独占一带)**
|
|
26
|
+
· B5 阶段行 `[140,212]` · B6 并行扇出 `[212,330]` · B7 角色 chip `[334,382]` · B8 工件脚注 `[400,440]`。
|
|
27
|
+
两个徽标各自落在**它注记的方框正上方**(硬门 → 规格评审 `x 428..532`;确认门 → 方案确认 `x 548..652`,
|
|
28
|
+
徽标 x 区间被断言**包含于**对应方框);阶段行下移 24px,全图高度 `430 → 460`;阶段间箭头的线段改为在箭头**起点**处结束,
|
|
29
|
+
不再与箭头包围盒相交。
|
|
30
|
+
|
|
31
|
+
信息量未减:9 阶段、硬门/确认门的区分(规格评审=硬门;方案确认=确认门,默认开启、可在设置里关)、
|
|
32
|
+
DAG 并行扇出、角色 chip、工件脚注全部保留。
|
|
33
|
+
|
|
34
|
+
### 类级防复发:**真重叠自检**(这一环上一轮缺失)
|
|
35
|
+
|
|
36
|
+
上一轮只做了"矩形不越界"的几何自检,**抓不到"文字压文字"**。本次补上一次性自检脚本(`/tmp`,不提交):
|
|
37
|
+
|
|
38
|
+
- 对每个 `<text>`/`<rect>`/`<path>` **估算包围盒**(CJK/全角按 `1.0em`、拉丁/数字按 `0.6em`,高 `1.2×font-size`,
|
|
39
|
+
上 `0.9` / 下 `0.3` 于基线;`path` 按 `M/H/V/L/l/v` 逐段追踪绝对坐标);
|
|
40
|
+
- **两两检测"部分相交"**(完全包含=父子/背景关系,允许并单独列出);
|
|
41
|
+
- **校验元素不跨带**(强制分带布局);另做 x 越界与"徽标在对应方框正上方"的语义断言。
|
|
42
|
+
|
|
43
|
+
有效性验证:脚本先对 **1.3.6 的两张图**运行,**复现了报告里的两处重叠**(坐标级:副标题 `64,95.4→682.8,112.2` × `12` `636,94.8→669.6,128.4`;
|
|
44
|
+
`rect@446,88` × 图例第三项 `420,96.1→519,109.3`);修复后两张图 **0 部分相交、0 跨带**(hero 190 对、pipeline 3403 对比较)。
|
|
45
|
+
|
|
46
|
+
### npm 页面上的 README 图片
|
|
47
|
+
|
|
48
|
+
`files` 未含 `docs/` ⇒ README 里的**相对**路径在 npm 页面渲染不到。改为**绝对地址**
|
|
49
|
+
`https://raw.githubusercontent.com/yangdcm/dsh-expert-team/main/docs/images/<file>`(中英各 6 处),
|
|
50
|
+
`LICENSE` 链接同样改为绝对地址。这样 GitHub、npm、以及将来插件市场的抽图都能用,且**不必**动 `files`(不增大产物)。
|
|
51
|
+
|
|
52
|
+
## 1.3.6
|
|
53
|
+
|
|
54
|
+
**文档与素材:README 重写成"能一眼看懂它在干什么"的结构,并补上手绘矢量图。**
|
|
55
|
+
|
|
56
|
+
纯文档/资产版本 —— `lib/`、`client.js` **零改动**,无依赖变化,`files` 字段未动。
|
|
57
|
+
|
|
58
|
+
### README(中英一致)
|
|
59
|
+
|
|
60
|
+
- 新骨架:一句话组队交付 → **一行关键指标** → 流水线图 → **30 秒看懂**(阶段 → 谁在做 → 落哪个工件,
|
|
61
|
+
工件名全部取自包内模板与代码)→ 为什么不是"一个 agent 硬做" → **看一眼它在干什么**(图 2–5,逐图编号图注)
|
|
62
|
+
→ 它为什么可靠 → 安装/上手/插件结构/开发/排障/自定义预设/**诚实边界**/兼容性/许可。
|
|
63
|
+
- 新增"它为什么可靠"一节,把工程纪律写成可核对的卖点:状态机由**插件代码**强制(`lib/interception.js` 挂
|
|
64
|
+
`tools/post-execute`)、零依赖零构建零安装钩子、**80 个测试文件**、**136 条变异目录**、多组棘轮
|
|
65
|
+
(`vocab-consistency` / `scan-single-source` / `write-bypass-ratchet` / `settings-consumers` / `state-perf-guard`)、
|
|
66
|
+
"两种零要分得清"、失败必须出声。
|
|
67
|
+
- 关键数字都标注了出处(`lib/vocab.js`、`presets/expert-team/agent.cordis.yml`、`package.json`),不写没有出处的指标;
|
|
68
|
+
性能修复的端到端数字明确标注**待实机复测**。
|
|
69
|
+
|
|
70
|
+
### 新增素材
|
|
71
|
+
|
|
72
|
+
- `docs/images/pipeline.svg` —— 手绘矢量:9 阶段流水线、**硬门**(规格评审)与**确认门**(方案确认,默认开、可关)
|
|
73
|
+
的区分、实现阶段的依赖 DAG 并行扇出、每阶段下挂角色 chip。
|
|
74
|
+
- `docs/images/hero.svg` —— 横幅(深色底、项目名、一句话、三个数字)。
|
|
75
|
+
- `docs/images/settings.png` —— 官方 `设置 →「专家团」` 分节截图(18 项、中文标签、改动即保存并即时生效)。
|
|
76
|
+
- 两张 SVG 均为**纯矢量**:无脚本、无 `<style>`、无外部引用(属性直挂,避免被托管方消毒器剥掉样式)。
|
|
77
|
+
|
|
78
|
+
### 已知取舍
|
|
79
|
+
|
|
80
|
+
- `files` 未包含 `docs/`,因此 **npm 页面上的 README 图片可能不显示**(GitHub 上正常)。若要两处都显示,
|
|
81
|
+
需要把 `docs/images` 加进 `files`(改变产物契约)或改用绝对图片地址 —— 本轮**有意未改**,留待决定。
|
|
82
|
+
|
|
6
83
|
## 1.3.5
|
|
7
84
|
|
|
8
85
|
**性能:修掉 `/state` 的 30 秒级阻塞(它会把整个 `dsh web` 一起拖慢)**,另带两件早已排定的小事。
|
package/README.en.md
CHANGED
|
@@ -3,70 +3,143 @@
|
|
|
3
3
|
English | [中文](README.md)
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@yangdcm/dsh-expert-team)
|
|
6
|
-
[](LICENSE)
|
|
6
|
+
[](https://github.com/yangdcm/dsh-expert-team/blob/main/LICENSE)
|
|
7
7
|
[](https://github.com/yangdcm/dsh-expert-team/actions/workflows/ci.yml)
|
|
8
8
|
|
|
9
|
+

|
|
10
|
+
|
|
9
11
|
> **One sentence in, a gated team delivery out.** `/team build a payments module with login`
|
|
10
12
|
> assembles a 12-role expert team and runs
|
|
11
13
|
> clarify → research → design → spec-review → plan-approval → implement → review → test → deliver,
|
|
12
14
|
> with implementers editing your workspace directly and every hand-off persisted as a reviewable artifact.
|
|
13
15
|
|
|
14
|
-
A plugin for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (dsh)
|
|
15
|
-
**
|
|
16
|
+
A plugin for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (dsh):
|
|
17
|
+
**zero runtime dependencies, no build step, no install hooks.**
|
|
18
|
+
|
|
19
|
+
| 12 roles | 9 phases | 80 test files | 0 runtime deps | 0 build steps |
|
|
20
|
+
|---|---|---|---|---|
|
|
21
|
+
| own persona / `toolFilter` / `maxDepth: 1` | 1 hard gate + 1 approval gate | incl. a 136-entry mutation catalog and several ratchets | `dependencies: {}` | no bundler, no `prepare` hook |
|
|
16
22
|
|
|
17
|
-

|
|
19
|
-

|
|
23
|
+

|
|
20
24
|
|
|
21
|
-
<sub>
|
|
25
|
+
<sub>Figure 1: the 9-phase gated pipeline. `spec-review` is a **hard gate** — if the SPEC.md
|
|
26
|
+
"boundaries and prohibitions" section is empty, the run does not advance (`lib/interception.js`).
|
|
27
|
+
`plan-approval` is an approval gate that is **on by default** (`identity.keepPlanGate`, can be turned off in settings).
|
|
28
|
+
The `implement` phase **fans out** along the dependency DAG: several implementers start at once, each touching only its own files.</sub>
|
|
22
29
|
|
|
23
30
|
---
|
|
24
31
|
|
|
25
|
-
##
|
|
32
|
+
## In 30 seconds
|
|
33
|
+
|
|
34
|
+
```text
|
|
35
|
+
$ /team build a payments module with login
|
|
36
|
+
│
|
|
37
|
+
├─ clarify pm pins down boundaries & acceptance → SPEC.md ("boundaries and prohibitions")
|
|
38
|
+
├─ research researcher evidence and options → RESEARCH.md
|
|
39
|
+
├─ design architect module split, dependency DAG → PLAN.md
|
|
40
|
+
├─ spec-review reviewer ▣ HARD GATE: no boundaries, no pass ← cannot advance
|
|
41
|
+
├─ plan-approval you ▣ approval gate (on by default)
|
|
42
|
+
├─ implement backend … fan out along the DAG → edits your workspace directly
|
|
43
|
+
├─ review sec·reviewer independent review (cross-model) → REVIEW.md
|
|
44
|
+
├─ test qa repro, coverage, regressions → TEST.md
|
|
45
|
+
└─ deliver docs wrap-up and cost → SUMMARY.md · METRICS.md
|
|
46
|
+
|
|
47
|
+
Persisted throughout: TASKS.json · ROSTER.json · STATE.json · AUTHORITY.md · RUN.log.md
|
|
48
|
+
On disk at: <your workspace>/team/<run-id>/
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
<sub>This is the "phase → who works → which artifact" mapping (phase names come from the single source
|
|
52
|
+
`lib/vocab.js`; artifact names are taken from the shipped templates and code). To watch what it is doing
|
|
53
|
+
*right now*, use the overlay in `dsh web`, or `/team canvas` for the full-screen canvas.</sub>
|
|
54
|
+
|
|
55
|
+
## Why not "one agent doing it all"
|
|
26
56
|
|
|
27
57
|
A single agent doing large work fails in three predictable ways: **context drift** (long tasks wander),
|
|
28
|
-
**self-review** (nobody verifies independently), and **rework that never converges**.
|
|
29
|
-
|
|
58
|
+
**self-review** (nobody verifies independently), and **rework that never converges**. Four mechanisms
|
|
59
|
+
answer them:
|
|
30
60
|
|
|
31
61
|
| Mechanism | How |
|
|
32
62
|
|---|---|
|
|
33
|
-
| **Role separation** | 12 roles, each with its own persona, tool boundary (`toolFilter`) and delegation depth (`maxDepth: 1`)
|
|
34
|
-
| **Phase
|
|
35
|
-
| **Quality gates
|
|
36
|
-
| **Convergence
|
|
37
|
-
|
|
38
|
-
##
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
63
|
+
| **Role separation** | 12 roles, each with its own persona, tool boundary (`toolFilter`) and delegation depth (`maxDepth: 1`); product/architecture roles only read and write planning artifacts, review/security are read-only, only implementers touch code |
|
|
64
|
+
| **Phase gates** | 9 phases; every hand-off travels two channels — a structured return value **and** an artifact file. State never rides on chat history |
|
|
65
|
+
| **Quality gates** | State-machine consistency is **enforced by plugin code**, not requested in a prompt: a task cannot be marked completed while unfinished, quality issues must be adjudicated by qa/reviewer, coverage gaps and over-budget rework are caught — violations show up **live** in the overlay and in `/team status` |
|
|
66
|
+
| **Convergence & accounting** | Every run records tokens, elapsed time, time-to-first-artifact and a closing budget; `/team learn` distills cross-run experience and feeds it back before the next run starts |
|
|
67
|
+
|
|
68
|
+
## What it looks like in action
|
|
69
|
+
|
|
70
|
+

|
|
71
|
+
|
|
72
|
+
<sub>Figure 2: **gate violations**. Look at the banner at the top — the violation and its refusal reason
|
|
73
|
+
(e.g. "SPEC.md's boundary section has entered `implement` but still has no 'expected rejection' row")
|
|
74
|
+
is decided by `lib/interception.js`, hooked onto the host's `tools/post-execute` waterfall, and surfaced
|
|
75
|
+
immediately. This is code, not a prompt reminder.</sub>
|
|
76
|
+
|
|
77
|
+

|
|
78
|
+
|
|
79
|
+
<sub>Figure 3: **the roster**. Look at the member list — who is running, on which model, and what it is doing;
|
|
80
|
+
expand a member for its tasks and artifacts. Models are configurable per role; heterogeneous models are used for cross-checking.</sub>
|
|
81
|
+
|
|
82
|
+

|
|
83
|
+
|
|
84
|
+
<sub>Figure 4: **phases and artifacts**. Look at the phase bar and the preview pane — the current phase, the phases
|
|
85
|
+
already passed, and the actual body of the artifact written in that phase (artifacts are the single source of truth; the overlay is just a view of them).</sub>
|
|
86
|
+
|
|
87
|
+

|
|
88
|
+
|
|
89
|
+
<sub>Figure 5: **settings**. Look at the official `Settings → Expert team` page — 18 settings, Chinese labels,
|
|
90
|
+
**saved on change and applied immediately** (caps, rounds, the tier gate and the oscillation detector are recomputed
|
|
91
|
+
in-process). Values live in the host namespace `expert-team`, so they travel with the plugin market's backup/restore.</sub>
|
|
92
|
+
|
|
93
|
+
## Why it is dependable
|
|
94
|
+
|
|
95
|
+
- **The state machine is enforced by plugin code, not requested by prompt.** `lib/interception.js` moves the
|
|
96
|
+
"task-ledger contract" and the "spec boundary" rules onto the host's `tools/post-execute` waterfall:
|
|
97
|
+
duplicate ids / cycles / self-dependencies are rejected on the spot (`HARD_GRAPH_CODES`), and an empty SPEC
|
|
98
|
+
boundary section cannot enter `implement` (`SPEC_COMPLETE_PHASES`). **Silence in the spec means permission —
|
|
99
|
+
that is the number-one source of rework.**
|
|
100
|
+
- **Zero runtime dependencies, zero devDependencies, no build step, no `prepare`/`postinstall` hooks.**
|
|
101
|
+
What you install is exactly what runs; there is no "unknown script at install time" layer.
|
|
102
|
+
- **80 test files plus a 136-entry mutation catalog.** `npm run test:all` needs no `install` (it is what CI runs);
|
|
103
|
+
the mutation catalog requires every mutant to be killed by at least one test — the suite is not "green",
|
|
104
|
+
it is *able to catch errors*.
|
|
105
|
+
- **Several ratchet tests** pin down rules that were already thought through, so they cannot quietly regress:
|
|
106
|
+
`vocab-consistency` (one source for vocabulary and role labels), `scan-single-source` (no fact with two homes),
|
|
107
|
+
`write-bypass-ratchet` (no write path may bypass interception), `settings-consumers`
|
|
108
|
+
(**every setting must have a consumer**; the allow-list is compared as a set, so it can only shrink),
|
|
109
|
+
`state-perf-guard` (sub-session timing must perform **zero** log reads — a performance regression fails the suite).
|
|
110
|
+
- **Two kinds of zero, kept apart.** "I don't know what exists" must not look like "there is nothing":
|
|
111
|
+
a failed tool-face narrowing distinguishes `no-known-names` from `nothing-to-deny`; when `/state` cannot obtain
|
|
112
|
+
a timestamp it returns `hasTimestamp: false` instead of passing `0` off as a measurement.
|
|
113
|
+
- **Failures must be loud.** Out-of-bounds writes, artifact divergence and over-budget rework always raise an
|
|
114
|
+
explicit error; nothing is truncated silently — silent failure is the most expensive bug class in this repo.
|
|
115
|
+
- **Performance is measured and guarded.** `/state` used to read every sub-session log in full: measured at
|
|
116
|
+
7.1–9.8 s warm and 283.6 s cold (75 sub-sessions), and it blocked the whole `dsh web` event loop. 1.3.5
|
|
117
|
+
replaced that with a table lookup (measured at 0.0026 ms per call, zero `readSession` calls);
|
|
118
|
+
**the end-to-end post-fix number is still pending a re-measurement on a real host**.
|
|
119
|
+
`state-perf-guard.test.mjs` keeps it from coming back.
|
|
45
120
|
|
|
46
121
|
## Install
|
|
47
122
|
|
|
48
123
|
**Requirements**
|
|
49
124
|
|
|
50
|
-
- `dsh web` (developed and verified
|
|
125
|
+
- `dsh web` (developed and verified on **0.1.5-rc.1**; earlier versions are untested)
|
|
51
126
|
- Node.js ≥ 20
|
|
52
|
-
- The 12 role tools (`subagent_pm
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
config-level boundary guarantees.
|
|
127
|
+
- The 12 role tools (`subagent_pm` / `subagent_architect` / …) are available when the session uses the
|
|
128
|
+
**"Expert team mode"** preset; otherwise the plugin falls back to the generic `subagent`
|
|
129
|
+
(role personas go into the prompt) — nothing is lost except the configuration-level boundary guarantees
|
|
56
130
|
|
|
57
|
-
**Option 1
|
|
131
|
+
**Option 1: command line (recommended)**
|
|
58
132
|
|
|
59
133
|
```sh
|
|
60
134
|
dsh plugin --profile web add @yangdcm/dsh-expert-team
|
|
61
135
|
# then restart dsh web so the new bundle joins the composition
|
|
62
136
|
```
|
|
63
137
|
|
|
64
|
-
**Option 2
|
|
138
|
+
**Option 2: plugin market** (listing not submitted yet ⇒ it may not be searchable today)
|
|
65
139
|
|
|
66
|
-
|
|
67
|
-
```
|
|
140
|
+
Once listed: `dsh web` → **Settings → Plugin market** → search "expert team" → install → refresh the page.
|
|
68
141
|
|
|
69
|
-
**Option 3
|
|
142
|
+
**Option 3: from source (development / unpublished)**
|
|
70
143
|
|
|
71
144
|
```sh
|
|
72
145
|
cd ~/.dsh/profiles/web
|
|
@@ -75,141 +148,157 @@ cd ~/.dsh/profiles/web
|
|
|
75
148
|
pnpm install && dsh web
|
|
76
149
|
```
|
|
77
150
|
|
|
78
|
-
> **The skill is
|
|
79
|
-
>
|
|
80
|
-
>
|
|
81
|
-
> has no skill registry
|
|
151
|
+
> **The skill is not copied to disk**: on load the plugin registers the `expert-team` skill as a **runtime entry**
|
|
152
|
+
> in the host's skill registry (relative resources point back into the package via `resourceBase`), so nothing
|
|
153
|
+
> appears under `$DSH_HOME/skills/` — uninstalling leaves no residue. It only falls back to copying into
|
|
154
|
+
> `$DSH_HOME/skills/` when the host has no skill registry.
|
|
82
155
|
>
|
|
83
|
-
> **The
|
|
84
|
-
>
|
|
85
|
-
>
|
|
86
|
-
>
|
|
156
|
+
> **The "Expert team mode" preset is copied** into `$DSH_HOME/.agent-presets/` (the host exposes no runtime API
|
|
157
|
+
> to add a scan root), but it carries a version stamp: on upgrade the whole directory is re-laid, so it never
|
|
158
|
+
> silently stays behind. **The plugin lays it down at load time** — after `/team uninstall`, a restart of
|
|
159
|
+
> `dsh web` re-lays it automatically; no manual rescue needed.
|
|
87
160
|
>
|
|
88
|
-
> **
|
|
89
|
-
>
|
|
161
|
+
> **Where settings live**: **Settings → Expert team** — a full page inside the official settings menu
|
|
162
|
+
> (the `settings.section` slot, `id: expert-team`, `order: 50`), sharing the same entry point and panel chrome
|
|
163
|
+
> as other plugins' settings. The data layer is the host namespace `expert-team` (owned by the host, travels with
|
|
164
|
+
> the plugin market's **backup and restore**; after a change, caps/rounds/the tier gate are recomputed
|
|
165
|
+
> **in-process** — no restart). The overlay's old "settings" tab was removed so the same form renders in one place.
|
|
166
|
+
> **Honest boundary**: `default roster` (an array of role ids) is deliberately not part of the host schema
|
|
167
|
+
> (unreliable to express there); the control on that page and `$DSH_HOME/expert-team/settings.json` cover it.
|
|
168
|
+
> When the host has no settings service, every setting falls back to that file.
|
|
90
169
|
>
|
|
91
|
-
> **
|
|
92
|
-
> (
|
|
93
|
-
>
|
|
94
|
-
> with the plugin market's **backup and restore**, and a changed value recomputes limits, round caps and the tier
|
|
95
|
-
> gate in-process — no restart). The overlay's old "settings" tab has been removed: one form, one place.
|
|
96
|
-
> **Honest boundary**: the default roster (an array of role ids) is deliberately *not* in the host schema (its value
|
|
97
|
-
> type cannot be expressed reliably); it stays with the corresponding control on that page and
|
|
98
|
-
> `$DSH_HOME/expert-team/settings.json`. On a host with no settings service every setting falls back to that file.
|
|
99
|
-
>
|
|
100
|
-
> **The A-line switch**: the "narrow the lead's tool face" gate (`gates.leadToolFace`, default `on`)
|
|
101
|
-
> decides whether execution tools (`bash/write/edit/grep/glob`) are taken away from the lead and given
|
|
102
|
-
> to the role subagents. Turn it off with `config.leadToolFace` or `DSH_EXPERT_TEAM_LEAD_TOOLFACE=off`.
|
|
170
|
+
> **The A-line switch**: "Gates → Narrow the lead's tool face" (`gates.leadToolFace`, default `on`) decides whether
|
|
171
|
+
> execution tools (`bash/write/edit/grep/glob`) are taken away from the lead and given to the role subagents.
|
|
172
|
+
> Turn it off with `config.leadToolFace` or `DSH_EXPERT_TEAM_LEAD_TOOLFACE=off`.
|
|
103
173
|
|
|
104
174
|
### After installing
|
|
105
175
|
|
|
106
|
-
1. **Restart `dsh web` once**: on load the plugin lays the
|
|
176
|
+
1. **Restart `dsh web` once**: on load the plugin lays the "Expert team mode" preset into
|
|
107
177
|
`$DSH_HOME/.agent-presets/expert-team` (version-stamped; upgrades re-lay the whole directory) —
|
|
108
|
-
**
|
|
109
|
-
subagent tools are in place (
|
|
110
|
-
2. Switch the session to
|
|
111
|
-
3. Change settings under **Settings
|
|
178
|
+
**you never create a preset by hand**. After the restart the preset appears in the picker and all 12 role
|
|
179
|
+
subagent tools are in place (see them under `Settings → Plugins → Plugin list → Session plugins`).
|
|
180
|
+
2. Switch the session to "Expert team mode", then run `/team <one-sentence goal>`.
|
|
181
|
+
3. Change settings under **Settings → Expert team** (values live in the host namespace `expert-team`, so they
|
|
112
182
|
travel with the plugin market's backup/restore).
|
|
113
183
|
|
|
114
|
-
**Troubleshooting**:
|
|
115
|
-
|
|
116
|
-
[Troubleshooting](#troubleshooting) section
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
### Custom presets (when you want to change expert-team's defaults)
|
|
120
|
-
|
|
121
|
-
- **Create**: `Settings → Agent presets → create a custom preset with "creation mode"` (its mechanism is
|
|
122
|
-
"copy an existing preset"; the result lands in `$DSH_HOME/.agent-presets/<id>/`).
|
|
123
|
-
- **To customise expert-team, copy 「专家团模式」 as the source under an id of your own** (e.g. `my-team`): the
|
|
124
|
-
copy already carries the 12 role tools and their skill directory, and your edits stay inside `my-team/`.
|
|
125
|
-
**Never edit files under `expert-team/`** — that copy belongs to the plugin and is re-laid wholesale on
|
|
126
|
-
load/upgrade.
|
|
127
|
-
- A newly created preset **may only appear in the picker after a `dsh web` restart** (the host reads its roster
|
|
128
|
-
at startup).
|
|
184
|
+
**Troubleshooting**: if the preset is gone or occupied by an unrelated preset of the same id, **one restart of
|
|
185
|
+
`dsh web` heals it** (the plugin re-lays it at load); alternatively run `/team <task>` once. See the
|
|
186
|
+
[Troubleshooting](#troubleshooting) section for the easiest trap to fall into: **do not** use the id
|
|
187
|
+
`expert-team` when creating a preset.
|
|
129
188
|
|
|
130
189
|
## Quick start
|
|
131
190
|
|
|
132
191
|
```
|
|
133
|
-
/team build a payments module with login # one-shot
|
|
134
|
-
/team --persist refactor the orders module # persistent live team
|
|
135
|
-
/team --
|
|
136
|
-
/team --
|
|
137
|
-
/team
|
|
138
|
-
/team
|
|
192
|
+
/team build a payments module with login # one sentence in, a one-shot team delivery out
|
|
193
|
+
/team --persist refactor the orders module # persistent live team: members can be re-tasked, survives sessions
|
|
194
|
+
/team --one-shot run a small chore # inverse override: run once even if persistence is the default
|
|
195
|
+
/team --no-code review the existing API # produce planning/review/test artifacts only, change no code
|
|
196
|
+
/team --code implement it # inverse override: touch code even if "artifacts only" is the default
|
|
197
|
+
/team --confirm a big redesign # create the run but do not dispatch; click "run" in the overlay
|
|
198
|
+
/team uninstall # reclaim what this plugin laid down under $DSH_HOME
|
|
199
|
+
/team status # phase, members, model plan and live violations for every run
|
|
200
|
+
/team resume <run-id> # resume across sessions
|
|
139
201
|
```
|
|
140
202
|
|
|
141
|
-
|
|
142
|
-
`/team
|
|
203
|
+
Full command list (`/team canvas` visual canvas, `/team codeindex` code index, `/team learn` self-learning,
|
|
204
|
+
`/team limit` quotas, `/team settle` cold-start settlement, …) — see `/team help`.
|
|
143
205
|
|
|
144
|
-
**Where
|
|
206
|
+
**Where artifacts land**
|
|
145
207
|
|
|
146
|
-
- `<your workspace>/team/<run-id>/` —
|
|
147
|
-
- `$DSH_HOME/expert-team/` — machine-local preferences and cross-project
|
|
208
|
+
- `<your workspace>/team/<run-id>/` — `SPEC / PLAN / TASKS / ROSTER / STATE / REVIEW / TEST / SUMMARY / RUN.log.md` etc.
|
|
209
|
+
- `$DSH_HOME/expert-team/` — machine-local preferences and cross-project experience: `settings.json`,
|
|
210
|
+
`session-runs.json`, `LEARNINGS.md`
|
|
148
211
|
|
|
149
212
|
## Layout
|
|
150
213
|
|
|
151
214
|
```
|
|
152
|
-
cordis.patch.yml the only composition contribution:
|
|
153
|
-
lib/command.js /team command: parse +
|
|
154
|
-
lib/validate.js pure validators for state machine
|
|
155
|
-
lib/
|
|
156
|
-
lib/
|
|
157
|
-
lib/
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
215
|
+
cordis.patch.yml the only composition contribution: a host-plane /team command line
|
|
216
|
+
lib/command.js /team command: parse + create workspace + install skill + launch team + 11 overlay routes
|
|
217
|
+
lib/validate.js pure-function validators for the state machine / quality gates / capacity caps
|
|
218
|
+
lib/interception.js moves the ledger contract and spec boundary onto tools/post-execute (gates in code)
|
|
219
|
+
lib/tier.js single source for the process-tier vocabulary
|
|
220
|
+
lib/vocab.js single source for phases/roles/tiers (both host and client derive from it)
|
|
221
|
+
lib/metrics/ token accounting, time-to-first-artifact, closing budget, METRICS rendering
|
|
222
|
+
lib/routes/ shared route helpers (uniform 405/500/JSON handling, local-origin guard)
|
|
223
|
+
client.js the client overlay (module-loader bundle, only require('react'))
|
|
224
|
+
skills/expert-team/ the orchestration "brain": SKILL.md + references/ + assets/templates/
|
|
225
|
+
presets/expert-team/ the "Expert team mode" preset: 12 role subagent tool instances
|
|
161
226
|
```
|
|
162
227
|
|
|
163
|
-
|
|
164
|
-
without a package
|
|
228
|
+
Almost all of the orchestration protocol lives in the skill rather than in code — so the team protocol can
|
|
229
|
+
evolve with the skill, without shipping a new package.
|
|
165
230
|
|
|
166
231
|
## Development
|
|
167
232
|
|
|
168
233
|
```sh
|
|
169
|
-
npm run test:all #
|
|
170
|
-
npm run rename <name> #
|
|
171
|
-
npm run check:name #
|
|
234
|
+
npm run test:all # 80 test files, zero dependencies, no install needed (this is what CI runs)
|
|
235
|
+
npm run rename <name> # after forking: syncs 4 package-name spellings across 13 files
|
|
236
|
+
npm run check:name # check for leftover placeholder package names
|
|
172
237
|
```
|
|
173
238
|
|
|
174
|
-
`npm run gate` (`gate:preset` / `gate:sync` / `gate:evidence` / `gate:bypass` / `gate:mutation`)
|
|
175
|
-
**
|
|
176
|
-
`$DSH_HOME`, and `gate:preset` borrows the Config
|
|
177
|
-
(
|
|
239
|
+
`npm run gate` (`gate:preset` / `gate:sync` / `gate:evidence` / `gate:bypass` / `gate:mutation`) are
|
|
240
|
+
**development-machine-only** gates: `gate:sync` compares against the bootstrap copy under your local
|
|
241
|
+
`$DSH_HOME`, and `gate:preset` borrows the Config schema shipped with the dsh installation
|
|
242
|
+
(auto-detected; override with `DSH_INSTALL`). They are therefore **not run in CI**.
|
|
178
243
|
|
|
179
244
|
## Troubleshooting
|
|
180
245
|
|
|
181
|
-
**
|
|
182
|
-
|
|
183
|
-
did not exist before 1.3.0.
|
|
184
|
-
|
|
185
|
-
**The
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
1.
|
|
190
|
-
|
|
191
|
-
2.
|
|
192
|
-
3.
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
**new session** (
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
246
|
+
**The "Expert team" page is missing from the settings menu?** Check the version (≥ 1.3.0):
|
|
247
|
+
`dsh plugin --profile web add @yangdcm/dsh-expert-team`, or `npm view @yangdcm/dsh-expert-team version`,
|
|
248
|
+
then **restart `dsh web`** — the page did not exist before 1.3.0.
|
|
249
|
+
|
|
250
|
+
**The preset shows as a bare id (`expert-team`) and the session has no role tools?** Then
|
|
251
|
+
`$DSH_HOME/.agent-presets/expert-team/` does not hold our copy (it was deleted, or an unrelated preset
|
|
252
|
+
took the id). Fix in this order:
|
|
253
|
+
|
|
254
|
+
1. run `/team <any small task>` — the plugin re-lays a version-stamped copy from the package (easiest; since 1.3.0
|
|
255
|
+
it is also laid down at plugin load);
|
|
256
|
+
2. or copy from the package: `cp -f <package>/presets/expert-team/{agent.cordis.yml,preset.yml} ~/.dsh/.agent-presets/expert-team/`;
|
|
257
|
+
3. **do not** create a preset with the same id in `Settings → Agent presets` — you would only get a copy of the
|
|
258
|
+
**source** you picked (e.g. standard mode), not our preset.
|
|
259
|
+
|
|
260
|
+
Then **restart `dsh web`** (the preset roster is read at startup; refreshing the page is not enough) and open a
|
|
261
|
+
**new session** (the preset is fixed when a session is created).
|
|
262
|
+
|
|
263
|
+
**The overlay opens slowly / `dsh web` feels sluggish?** Before 1.3.5, `/state` read every sub-session log in full
|
|
264
|
+
(measured 7–10 s warm, 283 s cold) and blocked the event loop. Upgrade to ≥ 1.3.5 and restart `dsh web`.
|
|
265
|
+
|
|
266
|
+
## Custom presets (when you want to change expert-team's defaults)
|
|
267
|
+
|
|
268
|
+
- **Create**: `Settings → Agent presets → create a custom preset with "Creator mode"` (the mechanism is
|
|
269
|
+
"copy an existing preset"; output lands in `$DSH_HOME/.agent-presets/<id>/`).
|
|
270
|
+
- **To customize the expert team, copy from "Expert team mode" and pick your own id** (e.g. `my-team`):
|
|
271
|
+
the copy comes with all 12 role tools and the skill directory, and your edits stay in `my-team/`.
|
|
272
|
+
**Never edit files in `expert-team/`** — that copy belongs to the plugin and is re-laid on load/upgrade.
|
|
273
|
+
- A newly created preset may only appear in the picker **after a restart of `dsh web`** (the host reads its
|
|
274
|
+
roster at startup).
|
|
275
|
+
|
|
276
|
+
## Honest boundaries
|
|
277
|
+
|
|
278
|
+
- **The local-origin guard is in place, but it is not authentication.** All 11 overlay routes validate the Host
|
|
279
|
+
header (against DNS rebinding), the Origin of mutating methods (against cross-site writes) and the client
|
|
280
|
+
address (against the LAN); mutating methods additionally require `application/json` (blocking form/text-plain
|
|
281
|
+
"simple requests" that skip preflight). `/file` goes through the host `ctx.fs` policy and reports 403 honestly
|
|
282
|
+
when a read is denied rather than **falling back to a raw read**.
|
|
283
|
+
**Residual risk, stated plainly**: any local non-browser process can forge arbitrary request headers, and dsh
|
|
284
|
+
plugins have no authentication model — so do not expose `dsh web` to an untrusted network (with the host
|
|
285
|
+
configured as `host: 0.0.0.0`, the guard only blocks clients that are not on loopback).
|
|
286
|
+
- **Web profile only**: the overlay and routes depend on `webServer`; without an overlay the command and the
|
|
287
|
+
artifacts still work.
|
|
288
|
+
- **Preset drift**: the shipped "Expert team mode" is a copy of the official `standard` preset plus the role tools;
|
|
289
|
+
if the host changes its built-in preset structure, this needs a sync. Upgrades re-lay the whole directory by
|
|
290
|
+
version stamp; `/team uninstall` reclaims it (a user-authored preset with the same name is never touched).
|
|
291
|
+
- **It intentionally runs `git status --porcelain` (read-only)** to judge artifact freshness.
|
|
292
|
+
- **Unwired settings are never dressed up as working.** Every setting either really takes effect or is marked
|
|
293
|
+
"not yet in effect" (driven by the single source `INERT_SETTINGS`) and watched by
|
|
294
|
+
`settings-consumers.test.mjs` — that table is currently empty.
|
|
295
|
+
|
|
296
|
+
## Compatibility
|
|
297
|
+
|
|
298
|
+
- `engines.dsh: >=0.1.5-rc.1`, declared in `package.json` under `dsh.compatibility` (`dshReleases` marks it
|
|
299
|
+
release by release); the plugin market uses it to decide whether this plugin fits your host.
|
|
300
|
+
- Node.js ≥ 20.
|
|
301
|
+
- Profile: `web` (see "Honest boundaries" above).
|
|
213
302
|
|
|
214
303
|
## License
|
|
215
304
|
|
package/README.md
CHANGED
|
@@ -3,44 +3,97 @@
|
|
|
3
3
|
[English](README.en.md) | 中文
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@yangdcm/dsh-expert-team)
|
|
6
|
-
[](LICENSE)
|
|
6
|
+
[](https://github.com/yangdcm/dsh-expert-team/blob/main/LICENSE)
|
|
7
7
|
[](https://github.com/yangdcm/dsh-expert-team/actions/workflows/ci.yml)
|
|
8
8
|
|
|
9
|
+

|
|
10
|
+
|
|
9
11
|
> **一句话组队交付**:`/team 做一个带登录的支付模块` —— 自动组建 12 角色专家团,走
|
|
10
12
|
> 澄清 → 调研 → 设计 → 规格评审 → 方案确认 → 实现 → 审查 → 测试 → 交付 的门控流水线,
|
|
11
13
|
> 实现者直接改你工作区的代码,全程留痕成可复核的工件。
|
|
12
14
|
|
|
13
|
-
装在 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 上的 dsh
|
|
14
|
-
|
|
15
|
+
装在 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 上的 dsh 插件:**零运行时依赖、无构建步骤、无安装钩子**。
|
|
16
|
+
|
|
17
|
+
| 12 角色 | 9 阶段 | 80 个测试文件 | 0 运行时依赖 | 0 构建步骤 |
|
|
18
|
+
|---|---|---|---|---|
|
|
19
|
+
| 各带人设 / `toolFilter` / `maxDepth: 1` | 含 1 道硬门 + 1 道确认门 | 含 136 条变异目录与多组棘轮 | `dependencies: {}` | 无 bundler、无 `prepare` 钩子 |
|
|
15
20
|
|
|
16
|
-

|
|
18
|
-

|
|
21
|
+

|
|
19
22
|
|
|
20
|
-
<sub
|
|
23
|
+
<sub>图 1:9 阶段门控流水线。「规格评审」是**硬门** —— SPEC.md 的「边界与禁止项」没填就不放行(`lib/interception.js`);「方案确认」是默认开启的**确认门**(`identity.keepPlanGate`,可在设置里关掉);「实现」阶段按依赖 DAG **并行扇出**,多个实现者同时开工、各自只改自己那份文件。</sub>
|
|
21
24
|
|
|
22
25
|
---
|
|
23
26
|
|
|
24
|
-
##
|
|
27
|
+
## 30 秒看懂
|
|
28
|
+
|
|
29
|
+
```text
|
|
30
|
+
$ /team 做一个带登录的支付模块
|
|
31
|
+
│
|
|
32
|
+
├─ 澄清 pm 问清边界与验收口径 → SPEC.md(含「边界与禁止项」)
|
|
33
|
+
├─ 调研 researcher 证据与选型 → RESEARCH.md
|
|
34
|
+
├─ 设计 architect 模块拆分与依赖 DAG → PLAN.md
|
|
35
|
+
├─ 规格评审 reviewer ▣ 硬门:边界没填不放行 ← 不过不进下一步
|
|
36
|
+
├─ 方案确认 你 ▣ 确认门(默认开,可关)
|
|
37
|
+
├─ 实现 backend … 按依赖 DAG 并行扇出 → 直接改你工作区的代码
|
|
38
|
+
├─ 审查 sec·reviewer 独立评审(换模型交叉验证) → REVIEW.md
|
|
39
|
+
├─ 测试 qa 复现、覆盖、回归 → TEST.md
|
|
40
|
+
└─ 交付 docs 收尾结论与成本 → SUMMARY.md · METRICS.md
|
|
41
|
+
|
|
42
|
+
全程留痕:TASKS.json · ROSTER.json · STATE.json · AUTHORITY.md · RUN.log.md
|
|
43
|
+
落盘位置:<你的工作区>/team/<run-id>/
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
<sub>上表是「阶段 → 谁在做 → 落哪个工件」的对应关系(阶段名出自 `lib/vocab.js` 的唯一真源,工件名取自包内模板与代码)。想连它**正在做什么**一起看,用 `dsh web` 里的浮层,或 `/team canvas` 打开全屏画布。</sub>
|
|
25
47
|
|
|
26
|
-
|
|
27
|
-
|
|
48
|
+
## 为什么不是「一个 agent 硬做」
|
|
49
|
+
|
|
50
|
+
单个 agent 干大活有三个固定失败模式:**上下文漂移**(长任务越做越偏)、**自己批自己**(没人独立验证)、
|
|
51
|
+
**返工不收敛**(同一个问题来回改)。专家团用四件事对付它们:
|
|
28
52
|
|
|
29
53
|
| 机制 | 做法 |
|
|
30
54
|
|---|---|
|
|
31
55
|
| **角色分工** | 12 个角色各带独立人设、工具边界(`toolFilter`)、委派深度(`maxDepth: 1`);产品/架构只读写计划工件,审查/安全只读,实现者才动代码 |
|
|
32
|
-
| **阶段门控** | 9 个阶段,每次交接走「结构化返回值 +
|
|
33
|
-
| **质量门禁** | 状态机一致性由**插件代码强制**(不是提示词请求):任务未完成不能标 completed、质量问题必须由 qa/reviewer
|
|
34
|
-
| **收敛与记账** | 每 run 记 token/耗时/首产物时间/收尾预算;`/team learn` 跨 run
|
|
56
|
+
| **阶段门控** | 9 个阶段,每次交接走「结构化返回值 + 工件文件」双通道 —— 状态不靠聊天记录传递 |
|
|
57
|
+
| **质量门禁** | 状态机一致性由**插件代码强制**(不是提示词请求):任务未完成不能标 completed、质量问题必须由 qa/reviewer 裁决、覆盖率缺口、超轮次返工 —— 违规**实时**显示在浮层并计入 `/team status` |
|
|
58
|
+
| **收敛与记账** | 每 run 记 token/耗时/首产物时间/收尾预算;`/team learn` 跨 run 蒸馏经验,并在下次开工前回注 |
|
|
59
|
+
|
|
60
|
+
## 看一眼它在干什么
|
|
61
|
+
|
|
62
|
+

|
|
63
|
+
|
|
64
|
+
<sub>图 2:**门禁违规**。看顶部那条横幅 —— 违规项与拒绝理由(例如"SPEC.md 的边界章节已进入 `implement` 但仍无任何一行填写")由 `lib/interception.js` 挂在宿主 `tools/post-execute` 上当场判出后推出,不是提示词提醒。</sub>
|
|
35
65
|
|
|
36
|
-
|
|
66
|
+

|
|
37
67
|
|
|
38
|
-
|
|
39
|
-
前端(frontend) · 数据(dba) · 安全审计(sec) · 评审(reviewer) · 测试(qa) · 运维(devops) · 文档(docs)。
|
|
40
|
-
按任务复杂度裁剪:小活只起需要的角色。
|
|
68
|
+
<sub>图 3:**角色编制**。看成员列表 —— 谁在跑、用哪个模型、当前在做什么;展开任一成员可看它的任务与产物。模型可按角色分别配置,异构模型用于交叉验证。</sub>
|
|
41
69
|
|
|
42
|
-
|
|
43
|
-
|
|
70
|
+

|
|
71
|
+
|
|
72
|
+
<sub>图 4:**阶段与工件**。看阶段条与预览区 —— 当前阶段、已过阶段、以及该阶段真正写下的工件正文(工件是唯一真源,浮层只是它的视图)。</sub>
|
|
73
|
+
|
|
74
|
+

|
|
75
|
+
|
|
76
|
+
<sub>图 5:**设置**。看官方 `设置 →「专家团」` 这一页 —— 18 个设置项、中文标签、**改动即保存并即时生效**(上限/轮次/档位门/振荡检测在进程内重算);值存在宿主命名空间 `expert-team`,随插件市场的备份/恢复一起走。</sub>
|
|
77
|
+
|
|
78
|
+
## 它为什么可靠
|
|
79
|
+
|
|
80
|
+
- **状态机由插件代码强制,不由提示词请求。** `lib/interception.js` 把「台账契约」与「规格边界」两条规则搬到宿主的
|
|
81
|
+
`tools/post-execute` 瀑布上:重复 id / 环 / 自依赖当场顶回(`HARD_GRAPH_CODES`),SPEC 边界未填不许进实现
|
|
82
|
+
(`SPEC_COMPLETE_PHASES`)。**规格沉默等于允许,那正是头号返工源。**
|
|
83
|
+
- **零运行时依赖、零 devDependencies、无构建步骤、无 `prepare`/`postinstall` 钩子。** 装完就是能跑的那份代码,
|
|
84
|
+
没有"安装时执行未知脚本"这一层。
|
|
85
|
+
- **80 个测试文件 + 136 条变异目录。** `npm run test:all` 无需 `install` 即可跑(CI 跑的就是它);
|
|
86
|
+
`mutation-catalog` 要求每个变异体都至少被一个测试杀掉 —— 测试不是"跑绿了",而是"能抓到错"。
|
|
87
|
+
- **多组棘轮(ratchet)测试**,把"已经想清楚的规矩"钉住,防止悄悄退化:
|
|
88
|
+
`vocab-consistency`(术语与角色标签单一真源)、`scan-single-source`(同一事实不许有两个家)、
|
|
89
|
+
`write-bypass-ratchet`(写侧不许绕过拦截)、`settings-consumers`(**每个设置项都必须有消费者**,白名单集合相等 ⇒ 只减不增)、
|
|
90
|
+
`state-perf-guard`(子会话计时**零次**读日志,性能回归即红)。
|
|
91
|
+
- **两种零要分得清。** "我不知道有什么"与"确实没有"不长成同一个样子:工具面收窄失败时区分
|
|
92
|
+
`no-known-names` / `nothing-to-deny`;`/state` 取不到时间戳时给 `hasTimestamp: false`,而不是用 `0` 冒充。
|
|
93
|
+
- **失败必须出声。** 写侧越界、工件分叉、超轮次返工一律**显式报错**,不做静默截断 —— 静默失败是本仓最贵的 bug 类型。
|
|
94
|
+
- **性能有实测、也有护栏。** 曾经 `/state` 会逐条全量读子会话日志:实测热态 7.1–9.8 s、冷态 283.6 s(75 个子会话),
|
|
95
|
+
还会堵住整个 `dsh web` 的事件循环。1.3.5 改成只查表(实测 0.0026 ms/次、零次 `readSession`),
|
|
96
|
+
**修复后的端到端数字待实机复测**;`state-perf-guard.test.mjs` 守着它不许回退。
|
|
44
97
|
|
|
45
98
|
## 安装
|
|
46
99
|
|
|
@@ -61,7 +114,6 @@ dsh plugin --profile web add @yangdcm/dsh-expert-team
|
|
|
61
114
|
**方式二:插件市场**(收录尚未提交 ⇒ 目前可能搜不到)
|
|
62
115
|
|
|
63
116
|
若已被收录:`dsh web` → **设置 → 插件市场** → 搜索「专家团」→ 一键安装 → 刷新页面。
|
|
64
|
-
```
|
|
65
117
|
|
|
66
118
|
**方式三:从源码(开发/未发布时)**
|
|
67
119
|
|
|
@@ -76,11 +128,9 @@ pnpm install && dsh web
|
|
|
76
128
|
> (相对资源用 `resourceBase` 指回包内目录),所以 `$DSH_HOME/skills/` 下不会出现副本 ——
|
|
77
129
|
> 卸载即干净。宿主没有 skill 注册表时才会回退为复制到 `$DSH_HOME/skills/`。
|
|
78
130
|
>
|
|
79
|
-
> **「专家团模式」preset
|
|
80
|
-
>
|
|
81
|
-
>
|
|
82
|
-
>
|
|
83
|
-
> **插件加载时就把 preset 铺到位**:`/team uninstall` 回收之后,重启 `dsh web` 即会**自愈重铺**(不需要手工救)。
|
|
131
|
+
> **「专家团模式」preset 会复制**到 `$DSH_HOME/.agent-presets/`(宿主没有"运行时加扫描根"的 API),
|
|
132
|
+
> 但带版本戳:升级后整目录重铺,不会静默停在旧版本。**插件加载时就会把它铺到位** ——
|
|
133
|
+
> 所以 `/team uninstall` 回收之后,重启 `dsh web` 即会自愈重铺,不需要手工救。
|
|
84
134
|
>
|
|
85
135
|
> **设置在哪改**:**设置 →「专家团」** —— 官方设置菜单里的一整页(`settings.section` 槽,
|
|
86
136
|
> `id: expert-team`、`order: 50`),与其它插件的设置同一入口、同一套面板 chrome。数据层是宿主命名空间
|
|
@@ -104,19 +154,14 @@ pnpm install && dsh web
|
|
|
104
154
|
**排障**:预设丢了、或被同名预设占住 —— **重启一次 `dsh web` 即自愈**(插件加载会重铺),也可跑一次 `/team <任务>`。
|
|
105
155
|
细节见下面「排障」一节,其中包含那条最容易踩的坑:**不要**用 `expert-team` 这个 id 去「创建 preset」。
|
|
106
156
|
|
|
107
|
-
### 自定义预设(想改专家团默认行为时)
|
|
108
|
-
|
|
109
|
-
- **创建**:`设置 → Agent 预设 → 用「创造模式」创作自定义预设`(其机制是"复制一份既有预设",产出落在 `$DSH_HOME/.agent-presets/<id>/`)。
|
|
110
|
-
- **要定制专家团,请以「专家团模式」为源、换一个你自己的 id**(例如 `my-team`):复制出来的目录天然带上 12 个角色工具与它的 skill 目录,
|
|
111
|
-
你的改动只写在 `my-team/` 里。**永远不要改 `expert-team/` 里的文件** —— 那份是插件所有的,加载/升级会整目录重铺覆盖。
|
|
112
|
-
- 新建的预设**可能要重启 `dsh web` 后**才出现在选择器里(宿主名册在启动时读取)。
|
|
113
|
-
|
|
114
157
|
## 快速上手
|
|
115
158
|
|
|
116
159
|
```
|
|
117
160
|
/team 做一个带登录的支付模块 # 一句话组队(一次性,自动组队并交付)
|
|
118
161
|
/team --persist 重构订单模块 # 持久化活团队:成员可反复指挥、跨会话恢复
|
|
162
|
+
/team --one-shot 跑一个小活 # 反向覆盖:即使默认设了持久化,这次也只跑一次
|
|
119
163
|
/team --no-code 评审现有 API 设计 # 只产出计划/评审/测试工件,不改代码
|
|
164
|
+
/team --code 直接改 # 反向覆盖:即使默认设了"只出工件",这次也动代码
|
|
120
165
|
/team --confirm 大改版需求 # 先建 run、不自动派工,浮层点「执行」才开工
|
|
121
166
|
/team uninstall # 回收本插件铺到 $DSH_HOME 的副本(skill 默认走运行时注册,本就不落地)
|
|
122
167
|
/team status # 所有 run 的阶段、成员、模型计划、实时违规
|
|
@@ -137,11 +182,13 @@ pnpm install && dsh web
|
|
|
137
182
|
cordis.patch.yml 唯一的组合贡献:一个 host 面的 /team 命令行
|
|
138
183
|
lib/command.js /team 命令:解析 + 建工作区 + 装 skill + 触发团队 + 11 条浮层路由
|
|
139
184
|
lib/validate.js 状态机/质量门禁/容量上限的纯函数校验器
|
|
185
|
+
lib/interception.js 把「台账契约」「规格边界」搬到宿主 tools/post-execute 瀑布上(硬门在代码里)
|
|
140
186
|
lib/tier.js 流程档位词表的唯一真源
|
|
187
|
+
lib/vocab.js 阶段/角色/档位词表的唯一真源(host 与 client 两侧都从这里派生)
|
|
141
188
|
lib/metrics/ token 记账、首产物耗时、收尾预算、METRICS 渲染
|
|
142
|
-
lib/routes/ 路由层共享件(统一 405/500/JSON
|
|
189
|
+
lib/routes/ 路由层共享件(统一 405/500/JSON 处理、本机来源守卫)
|
|
143
190
|
client.js 客户端浮层(模块加载器 bundle,仅 require('react'))
|
|
144
|
-
skills/expert-team/ 编排「大脑」:SKILL.md + references/ +
|
|
191
|
+
skills/expert-team/ 编排「大脑」:SKILL.md + references/ + assets/templates/
|
|
145
192
|
presets/expert-team/ 「专家团模式」preset:12 个角色 subagent 工具实例
|
|
146
193
|
```
|
|
147
194
|
|
|
@@ -150,7 +197,7 @@ presets/expert-team/ 「专家团模式」preset:12 个角色 subagent 工
|
|
|
150
197
|
## 开发
|
|
151
198
|
|
|
152
199
|
```sh
|
|
153
|
-
npm run test:all #
|
|
200
|
+
npm run test:all # 80 个测试文件,零依赖、无需 install(CI 跑的就是它)
|
|
154
201
|
npm run rename <新包名> # fork 后改名:自动同步 13 个文件里 4 种包名写法
|
|
155
202
|
npm run check:name # 检查占位包名残留
|
|
156
203
|
```
|
|
@@ -174,9 +221,19 @@ dsh 安装里插件自带的 Config schema(dsh 路径自动探测,可用 `DS
|
|
|
174
221
|
|
|
175
222
|
改完**重启 `dsh web`**(预设名册在启动时固化,刷新页面不够),再开**新会话**(预设只在会话创建时固定)。
|
|
176
223
|
|
|
177
|
-
|
|
224
|
+
**浮层打开很慢 / 整个 `dsh web` 发卡?** 1.3.5 之前 `/state` 会逐条全量读子会话日志(实测热态 7–10 s、
|
|
225
|
+
冷态 283 s),并堵住事件循环。升级到 ≥ 1.3.5 后重启 `dsh web` 即可。
|
|
178
226
|
|
|
179
|
-
|
|
227
|
+
## 自定义预设(想改专家团默认行为时)
|
|
228
|
+
|
|
229
|
+
- **创建**:`设置 → Agent 预设 → 用「创造模式」创作自定义预设`(其机制是"复制一份既有预设",产出落在 `$DSH_HOME/.agent-presets/<id>/`)。
|
|
230
|
+
- **要定制专家团,请以「专家团模式」为源、换一个你自己的 id**(例如 `my-team`):复制出来的目录天然带上 12 个角色工具与它的 skill 目录,
|
|
231
|
+
你的改动只写在 `my-team/` 里。**永远不要改 `expert-team/` 里的文件** —— 那份是插件所有的,加载/升级会整目录重铺覆盖。
|
|
232
|
+
- 新建的预设**可能要重启 `dsh web` 后**才出现在选择器里(宿主名册在启动时读取)。
|
|
233
|
+
|
|
234
|
+
## 诚实边界
|
|
235
|
+
|
|
236
|
+
- **本机来源守卫已就位,但不是鉴权**:11 条浮层路由统一校验 Host(挡 DNS rebinding)、
|
|
180
237
|
写方法的 Origin(挡跨站写入)、客户端地址(挡局域网),写方法还要求 `application/json`
|
|
181
238
|
(挡 form / text-plain 这类不触发预检的"简单请求");`/file` 改走宿主 `ctx.fs` 策略,
|
|
182
239
|
读被策略拒绝时如实报 403 而**不退回裸读**。
|
|
@@ -186,7 +243,16 @@ dsh 安装里插件自带的 Config schema(dsh 路径自动探测,可用 `DS
|
|
|
186
243
|
- **preset 漂移**:随包的「专家团模式」是官方 `standard` preset 的拷贝 + 角色工具,
|
|
187
244
|
宿主若调整内置 preset 结构,需要同步更新。升级插件时会按版本戳整目录重铺;
|
|
188
245
|
`/team uninstall` 可回收它(用户自己写的同名 preset 不会被碰)。
|
|
189
|
-
-
|
|
246
|
+
- **会有意调用 `git status --porcelain`(只读)** 用于工件新鲜度判断。
|
|
247
|
+
- **未接线项不装作可用**:设置页的项要么真的生效,要么被标为「暂未生效」(由 `INERT_SETTINGS` 单一真源驱动),
|
|
248
|
+
并由 `settings-consumers.test.mjs` 盯着 —— 目前该表为空。
|
|
249
|
+
|
|
250
|
+
## 兼容性
|
|
251
|
+
|
|
252
|
+
- `engines.dsh: >=0.1.5-rc.1`,声明在 `package.json` 的 `dsh.compatibility`(`dshReleases` 逐版本标注);
|
|
253
|
+
插件市场按它判断"这个插件跟你的宿主兼不兼容"。
|
|
254
|
+
- Node.js ≥ 20。
|
|
255
|
+
- profile:`web`(见上「诚实边界」)。
|
|
190
256
|
|
|
191
257
|
## License
|
|
192
258
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yangdcm/dsh-expert-team",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.7",
|
|
4
4
|
"description": "dsh「专家团」bundle:一句自然语言自动组建/持久化一支 12 角色多智能体团队,共享工作区协议 + 阶段门控编排 + 结构化交接 + 质量门禁/自动调度,实现者直接改代码并产出持久工件;带 live 团队浮层(质量门禁/覆盖率/工件预览)。 · Role-based multi-agent expert team for DeepSeek Harness: one sentence in, a staged and gated team delivery out.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|