dsh-lead-mode 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 dsh-lead-mode contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.en.md ADDED
@@ -0,0 +1,146 @@
1
+ # dsh-lead-mode
2
+
3
+ Lead mode for DSH. Adds one `lead-mode` preset, one `lead-mode` skill, and one `/lead-mode` command.
4
+
5
+ It does three things, none of which touch dsh itself:
6
+
7
+ 1. Preset: switch to it and the model works as a Lead — decomposing, delegating, accepting.
8
+ 2. Skill: the Lead working method, loadable by the model or by you.
9
+ 3. Reminder: when the session has no Team tools, the model's first move is to tell you to enable the official Agent Teams instead of doing everything alone.
10
+
11
+ ## Enable the Team runtime first
12
+
13
+ Lead mode delegates through `spawn_teammate`, `send_message`, and `team_task_*`. Those come from the official dsh Team runtime, which this plugin does not ship.
14
+
15
+ ```bash
16
+ dsh plugin --profile <your profile name> add @deepseek-ai/dsh-experimental-agent-team-profile@0.2.1-rc.3
17
+ ```
18
+
19
+ **The version pin is required.** Without it npm resolves `latest`, which is 0.1.5-alpha.2 — built for 0.1.x hosts and it will not mount on a 0.2.1 host. `next` points at 0.2.1-rc.3, which is the correct one. Restart dsh afterwards.
20
+
21
+ Not sure whether it is installed? Run `/lead-mode` in dsh; it reports dependency state.
22
+
23
+ ## Install this plugin
24
+
25
+ Two routes, pick one.
26
+
27
+ From npm:
28
+
29
+ ```bash
30
+ dsh plugin --profile <your profile name> add dsh-lead-mode
31
+ ```
32
+
33
+ From GitHub (use this before the npm release):
34
+
35
+ ```bash
36
+ dsh plugin --profile <your profile name> add https://github.com/xiebaiyuan/dsh-lead-mode
37
+ ```
38
+
39
+ Restart dsh afterwards, then pick "Lead 模式" in the preset list.
40
+
41
+ ## Usage
42
+
43
+ Three steps.
44
+
45
+ **1. Switch to Lead mode.** Pick "Lead 模式" in a new session's preset list. The model's first system-prompt section becomes the Lead persona, and the reminder at its top goes in with it.
46
+
47
+ **2. Run `/lead-mode` to check dependencies.** This command delegates nothing; it only reports state:
48
+
49
+ - Whether the Team runtime is mounted, and its `maxMembers` when it is
50
+ - Whether the `lead-mode` preset registered
51
+ - The version-pinned install command when something is missing
52
+
53
+ Returns success when everything is in place, error when something is missing.
54
+
55
+ **3. Let the model work.** With the delegation tools in place, the model decomposes, delegates to teammates, and waits for all of them before wrapping up. Without them, its first move is to tell you to enable the Team runtime — it will not do everything alone, and it will not substitute `subagent` for a teammate.
56
+
57
+ ## Required official bundles and versions
58
+
59
+ This plugin ships none of the packages below. The host or an official bundle provides them; this plugin only declares version requirements in `peerDependencies`.
60
+
61
+ | Package | Requirement | Provided by | When missing |
62
+ |---|---|---|---|
63
+ | `@deepseek-ai/dsh-experimental-agent-team-profile` | `0.2.1-rc.3` | You install it explicitly | Cannot delegate; `/lead-mode` returns error; startup warn |
64
+ | `@deepseek-ai/dsh` | `>=0.2.1-rc.2` | Host | Will not install |
65
+ | `@deepseek-ai/cordis` | `^4.0.5` | Host | Will not install |
66
+ | `@deepseek-ai/schemastery` | `^3.18.5` | Host | Will not install |
67
+ | `@deepseek-ai/dsh-agent-preset-registry` | `>=0.2.1-rc.2` | Host | Preset row does not take effect; `/lead-mode` reports unknown |
68
+ | `@deepseek-ai/dsh-skill` | `>=0.2.1-rc.2` | Host | Skill not registered; startup warn |
69
+ | `@deepseek-ai/dsh-commands` | `>=0.2.1-rc.2` | Host | `/lead-mode` not registered; startup warn |
70
+
71
+ The target host version is `dshTarget` in `package.json`: `0.2.1-rc.3`.
72
+
73
+ ## Why the install command pins a version
74
+
75
+ `@deepseek-ai/dsh-experimental-agent-team-profile` has three dist-tags on npm:
76
+
77
+ | dist-tag | Version | Host it fits |
78
+ |---|---|---|
79
+ | `latest` | 0.1.5-alpha.2 | 0.1.x |
80
+ | `alpha` | 0.2.1-alpha.5 | the 0.2.1 prerelease line |
81
+ | `next` | 0.2.1-rc.3 | 0.2.1 |
82
+
83
+ Bare package name resolves `latest`, which installs 0.1.5-alpha.2. That build targets 0.1.x hosts and does not mount on a 0.2.1 host. After installing it, no Team tools appear in dsh and `/lead-mode` still reports "not mounted".
84
+
85
+ Measured on 2026-10-26 with npm 11.20.0:
86
+
87
+ ```
88
+ $ npm view @deepseek-ai/dsh-experimental-agent-team-profile version
89
+ 0.1.5-alpha.2
90
+ ```
91
+
92
+ So every install command in this plugin carries `@0.2.1-rc.3`: the persona prefix, the `/lead-mode` output, the startup warn, and SKILL.md. `test/preset.test.mjs` and `test/smoke.test.mjs` both assert that string, so a future edit cannot quietly drop back to the bare name.
93
+
94
+ For the `alpha` line, pin `@0.2.1-alpha.5` yourself; do not use the bare name.
95
+
96
+ ## Difference from the official standard preset
97
+
98
+ One place only: the persona. The other 21 rows are copied field for field from `standard`.
99
+
100
+ | Item | standard | lead-mode |
101
+ |---|---|---|
102
+ | persona prefix | `You are a coding agent powered by the {{model}} model.` | Chinese Lead persona plus an Agent Teams precondition check |
103
+ | other 21 rows | — | identical to standard, field for field |
104
+
105
+ The four classic subagent rows (`tool-subagent-control`, `tool-subagent-list-agents`, `tool-subagent`, `tool-subagent-fork`) stay enabled. Nothing is disabled. The Team tools are a host decision, not a preset decision.
106
+
107
+ ## Why the preset does not carry the Team runtime
108
+
109
+ `apply()` in `@deepseek-ai/dsh-experimental-tool-agent-team` listens on the global `agent/created` event and installs Team tools on every agent. It is a host-plane plugin; putting it in a preset would leak it into every session.
110
+
111
+ So this plugin stays at: preset, skill, reminder. Whether the Team runtime is on is decided by the user through the official profile package.
112
+
113
+ ## What `/lead-mode` reports
114
+
115
+ Three facts:
116
+
117
+ - Whether the Team runtime is mounted, and its `maxMembers` when it is
118
+ - Whether the `lead-mode` preset registered
119
+ - The version-pinned install command when something is missing
120
+
121
+ Returns success when everything is in place, error when something is missing. Missing dependencies are never silent.
122
+
123
+ ## Layout
124
+
125
+ ```
126
+ package.json package metadata; dsh.bundle.patch points at cordis.patch.yml
127
+ cordis.patch.yml two insert rows: this plugin and the lead-mode preset
128
+ lib/index.js host half: register the skill, register the command, startup check
129
+ skills/lead-mode/ the Lead working method
130
+ dsh-plugin.naming.json naming manifest
131
+ test/ behaviour assertions, zero dependencies
132
+ ```
133
+
134
+ ## Development
135
+
136
+ ```bash
137
+ node --check lib/index.js
138
+ node --test test/
139
+ node scripts/check-patch.mjs
140
+ ```
141
+
142
+ Tests are zero-dependency. No `npm install` needed.
143
+
144
+ ## License
145
+
146
+ MIT
package/README.md CHANGED
@@ -1,3 +1,146 @@
1
- # Temporary Holding Version
1
+ # dsh-lead-mode
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ DSH 的 Lead 模式。装好后多一个 `lead-mode` 预设、一个 `lead-mode` skill、一个 `/lead-mode` 命令。
4
+
5
+ 它做三件事,都不碰 dsh 本体:
6
+
7
+ 1. 预设:切过去,模型就按 Lead 的方式干活,拆活、派活、验收。
8
+ 2. skill:Lead 工作法写在里面,模型可以自己加载,你也可以手动加载。
9
+ 3. 提醒:本会话没有 Team 工具时,模型第一句就告诉你先去开官方 Agent Teams,不硬干。
10
+
11
+ ## 装之前先开 Team 运行时
12
+
13
+ Lead 模式靠 `spawn_teammate`、`send_message`、`team_task_*` 这些工具派活。它们由 dsh 官方的 Team 运行时提供,本插件不带。
14
+
15
+ ```bash
16
+ dsh plugin --profile <你的 profile 名> add @deepseek-ai/dsh-experimental-agent-team-profile@0.2.1-rc.3
17
+ ```
18
+
19
+ **必须带版本号。** 不带会装到 `latest` 上的 0.1.5-alpha.2,那是给 0.1.x 宿主用的,在 0.2.1 宿主上挂不上。`next` 指向的 0.2.1-rc.3 才对。装完重启 dsh。
20
+
21
+ 不确定装没装?进 dsh 敲 `/lead-mode`,它会报依赖状态。
22
+
23
+ ## 装本插件
24
+
25
+ 两条路,选一条。
26
+
27
+ 从 npm:
28
+
29
+ ```bash
30
+ dsh plugin --profile <你的 profile 名> add dsh-lead-mode
31
+ ```
32
+
33
+ 从 GitHub(还没发 npm 时用这条):
34
+
35
+ ```bash
36
+ dsh plugin --profile <你的 profile 名> add https://github.com/xiebaiyuan/dsh-lead-mode
37
+ ```
38
+
39
+ 装完重启 dsh。在预设列表里选「Lead 模式」。
40
+
41
+ ## 用法
42
+
43
+ 三步。
44
+
45
+ **1. 切到 Lead 模式。** 新会话的预设列表里选「Lead 模式」。切过去之后,模型的 system prompt 第一段就换成 Lead 人设,开头那段提醒跟着进去。
46
+
47
+ **2. 敲 `/lead-mode` 查依赖。** 这条命令不派活,只报状态:
48
+
49
+ - Team 运行时挂没挂,挂了报 `maxMembers`
50
+ - `lead-mode` 预设注册没注册
51
+ - 缺东西时给带版本号的安装命令
52
+
53
+ 依赖齐了返回 success,缺东西返回 error。
54
+
55
+ **3. 让模型干活。** 派活的工具齐了,模型会自己拆活、派给 teammate、等齐再收尾。工具不齐,它第一句就是让你去开 Team 运行时,不会自己硬干,也不会拿 `subagent` 顶替 teammate。
56
+
57
+ ## 依赖的官方 bundle 与版本
58
+
59
+ 本插件不捆绑下面这些包。它们由宿主或官方 bundle 提供,本插件只在 `peerDependencies` 里声明版本要求。
60
+
61
+ | 包 | 版本要求 | 谁提供 | 缺了会怎样 |
62
+ |---|---|---|---|
63
+ | `@deepseek-ai/dsh-experimental-agent-team-profile` | `0.2.1-rc.3` | 用户显式安装 | 派不了活,`/lead-mode` 报 error,启动 warn |
64
+ | `@deepseek-ai/dsh` | `>=0.2.1-rc.2` | 宿主 | 装不上 |
65
+ | `@deepseek-ai/cordis` | `^4.0.5` | 宿主 | 装不上 |
66
+ | `@deepseek-ai/schemastery` | `^3.18.5` | 宿主 | 装不上 |
67
+ | `@deepseek-ai/dsh-agent-preset-registry` | `>=0.2.1-rc.2` | 宿主 | 预设行不生效,`/lead-mode` 报「查不到」 |
68
+ | `@deepseek-ai/dsh-skill` | `>=0.2.1-rc.2` | 宿主 | skill 不注册,启动 warn |
69
+ | `@deepseek-ai/dsh-commands` | `>=0.2.1-rc.2` | 宿主 | `/lead-mode` 不注册,启动 warn |
70
+
71
+ 目标宿主版本写在 `package.json` 的 `dshTarget` 字段:`0.2.1-rc.3`。
72
+
73
+ ## 为什么安装命令要带版本号
74
+
75
+ `@deepseek-ai/dsh-experimental-agent-team-profile` 在 npm 上有三个 dist-tag:
76
+
77
+ | dist-tag | 版本 | 配哪个宿主 |
78
+ |---|---|---|
79
+ | `latest` | 0.1.5-alpha.2 | 0.1.x |
80
+ | `alpha` | 0.2.1-alpha.5 | 0.2.1 预发布线 |
81
+ | `next` | 0.2.1-rc.3 | 0.2.1 |
82
+
83
+ 裸写包名,npm 解析 `latest`,装到 0.1.5-alpha.2。这个版本是给 0.1.x 宿主用的,在 0.2.1 宿主上挂不上。装完 dsh 里看不到 Team 工具,`/lead-mode` 还是报「未挂载」。
84
+
85
+ 实测(2026-10-26,npm 11.20.0):
86
+
87
+ ```
88
+ $ npm view @deepseek-ai/dsh-experimental-agent-team-profile version
89
+ 0.1.5-alpha.2
90
+ ```
91
+
92
+ 所以本插件里所有出现安装命令的地方都带 `@0.2.1-rc.3`:persona prefix、`/lead-mode` 输出、启动 warn、SKILL.md。`test/preset.test.mjs` 与 `test/smoke.test.mjs` 都断言这个字符串在,防止以后被改回裸包名。
93
+
94
+ 要装 `alpha` 线的话自己换成 `@0.2.1-alpha.5`,别用裸名。
95
+
96
+ ## 与官方 standard 预设的差异
97
+
98
+ 只有 persona 一处。其余 21 行逐字段照抄 `standard`。
99
+
100
+ | 项 | standard | lead-mode |
101
+ |---|---|---|
102
+ | persona prefix | `You are a coding agent powered by the {{model}} model.` | 中文 Lead 人设 + Agent Teams 前置检查 |
103
+ | 其余 21 行 | — | 与 standard 逐字段相同 |
104
+
105
+ classic subagent 四行(`tool-subagent-control`、`tool-subagent-list-agents`、`tool-subagent`、`tool-subagent-fork`)保持启用,没有禁用。Team 工具由 host 决定,不由预设决定。
106
+
107
+ ## 为什么预设里不塞 Team 运行时
108
+
109
+ `@deepseek-ai/dsh-experimental-tool-agent-team` 的 `apply()` 监听全局 `agent/created`,给每一个 agent 装 Team 工具。它是 host 平面的插件,放进预设会漏到所有会话。
110
+
111
+ 所以本插件的定位是:预设 + skill + 提醒。开不开 Team 运行时,用户用官方 profile 包决定。
112
+
113
+ ## `/lead-mode` 输出什么
114
+
115
+ 三条信息:
116
+
117
+ - Team 运行时在不在,在的话报 `maxMembers`
118
+ - `lead-mode` 预设注册没有
119
+ - 缺东西时给带版本号的安装命令
120
+
121
+ 依赖齐了返回 success,缺东西返回 error。缺东西不会静默。
122
+
123
+ ## 目录
124
+
125
+ ```
126
+ package.json 包元数据,dsh.bundle.patch 指向 cordis.patch.yml
127
+ cordis.patch.yml 两行 insert:本插件 + lead-mode 预设
128
+ lib/index.js host 半边:注册 skill、注册命令、启动自检
129
+ skills/lead-mode/ Lead 工作法正文
130
+ dsh-plugin.naming.json 命名清单
131
+ test/ 行为断言,零依赖
132
+ ```
133
+
134
+ ## 开发
135
+
136
+ ```bash
137
+ node --check lib/index.js
138
+ node --test test/*.test.mjs
139
+ node scripts/check-patch.mjs
140
+ ```
141
+
142
+ 测试零依赖,不用 `npm install`。`test/` 目录形式只在 Node 22+ 被接受,Node 20 会用 glob 展开。
143
+
144
+ ## License
145
+
146
+ MIT
@@ -0,0 +1,170 @@
1
+ # dsh-lead-mode bundle patch
2
+ #
3
+ # Two inserts.
4
+ #
5
+ # 1. `dsh-lead-mode` — this plugin's own host half. It registers the `lead-mode`
6
+ # runtime skill, the `/lead-mode` slash command, and the startup check that
7
+ # warns when the Team runtime is missing. The loader id equals the package
8
+ # name, matching `dsh-plugin.naming.json` (`names.loaderIds`).
9
+ # 2. `preset-lead-mode` — the `lead-mode` agent preset. Its `config.plugins`
10
+ # mirrors the official `standard` preset row for row; the only difference is
11
+ # the persona prefix, which switches the session into Lead mode and states
12
+ # the Agent Teams prerequisite up front.
13
+ #
14
+ # This plugin does NOT mount the Team runtime. `@deepseek-ai/dsh-experimental-tool-agent-team`
15
+ # listens on the global `agent/created` event and installs Team tools on every
16
+ # agent, so it belongs to the host plane, not to a preset row. Users turn it on
17
+ # with the official profile package:
18
+ #
19
+ # dsh plugin --profile <name> add @deepseek-ai/dsh-experimental-agent-team-profile@0.2.1-rc.3
20
+ #
21
+ # The version pin matters: bare `npm i` resolves `latest`, which is 0.1.5-alpha.2
22
+ # and does not mount on a 0.2.1 host. `next` points at 0.2.1-rc.3.
23
+ - insert:
24
+ - id: dsh-lead-mode
25
+ name: 'dsh-lead-mode'
26
+ - id: preset-lead-mode
27
+ name: '@deepseek-ai/dsh-agent-preset'
28
+ config:
29
+ id: lead-mode
30
+ name: Lead 模式
31
+ description: 拆活、派活、验收。需要先开 dsh 官方 Agent Teams。
32
+ order: 5
33
+ plugins:
34
+ - id: persona
35
+ name: '@deepseek-ai/dsh-persona'
36
+ config:
37
+ prefix: |
38
+ 你是 Lead,负责拆活、派活、验收。动手的活尽量派出去。
39
+
40
+ 开工第一件事:检查本会话有没有 spawn_teammate、send_message、team_task_create、team_task_update 这些工具。
41
+
42
+ 没有的话,停下。只做一件事:告诉用户去开 dsh 官方的 Agent Teams,命令是
43
+
44
+ dsh plugin --profile <你的 profile 名> add @deepseek-ai/dsh-experimental-agent-team-profile@0.2.1-rc.3
45
+
46
+ 不带版本号会装到 0.1.5-alpha.2,和 0.2.1 宿主对不上。装完重启 dsh。
47
+
48
+ 这是本插件存在的主要理由。没有这些工具,你派不了活。不要自己硬干,不要假装能派活,也不要拿 subagent 凑数顶替 teammate。
49
+
50
+ 有这些工具,就按 Lead 工作法干活:
51
+
52
+ - 派活自包含。teammate 看不到你的上下文,把目标、约束、验收标准、已知失败、绝对路径都写进 prompt。
53
+ - 写作用域不重叠。一人一块文件。分不开的活排成依赖。
54
+ - 共享任务走 list、get、claim(带 revision)、干、complete。
55
+ - 等齐必需的 teammate 再给最终答复。等之前先 list_agents 确认有人 running。
56
+ - 最终验证自己做:跑测试、看 diff、核数字。不要只信回报。
57
+ - id: agent-instructions
58
+ name: '@deepseek-ai/dsh-agent-instructions'
59
+ config:
60
+ maxBytes: 65536
61
+ - id: time-context
62
+ name: '@deepseek-ai/dsh-time-context'
63
+ - id: tool-bash
64
+ name: '@deepseek-ai/dsh-tool-bash'
65
+ disabled: !!js process.platform === 'win32'
66
+ - id: tool-pwsh
67
+ name: '@deepseek-ai/dsh-tool-pwsh'
68
+ disabled: !!js process.platform !== 'win32'
69
+ - id: tool-fs
70
+ name: '@deepseek-ai/dsh-tool-fs'
71
+ - id: tool-fs-search
72
+ name: '@deepseek-ai/dsh-tool-fs-search'
73
+ config:
74
+ sampleOverCapGlobResults: false
75
+ - id: tool-jobs
76
+ name: '@deepseek-ai/dsh-tool-jobs'
77
+ - id: tool-schedule
78
+ name: '@deepseek-ai/dsh-tool-schedule'
79
+ - id: skill-filesystem
80
+ name: '@deepseek-ai/dsh-skill-filesystem'
81
+ - id: tool-skill
82
+ name: '@deepseek-ai/dsh-tool-skill'
83
+ - id: command-goal
84
+ name: '@deepseek-ai/dsh-command-goal'
85
+ - id: tool-goal
86
+ name: '@deepseek-ai/dsh-tool-goal'
87
+ - id: planning
88
+ name: cordis:group
89
+ group: true
90
+ isolate:
91
+ planMode: true
92
+ config:
93
+ - id: plan-mode
94
+ name: '@deepseek-ai/dsh-plan-mode'
95
+ config:
96
+ section: |
97
+ You are in plan mode. Stay in plan mode until the user approves your plan through exit_plan_mode or switches the session mode. Imperative language to implement changes means plan the implementation, not execute it. A user's conversational agreement — including an answer confirming something you asked — approves nothing and does not end plan mode; fold the confirmed decision into the plan and submit it through exit_plan_mode.
98
+
99
+ Explore first. Use non-mutating reads, searches, static analysis, and checks to ground the plan in the actual repository. Do not edit or write files, change configuration, run formatters or code generation that rewrites tracked files, commit, or otherwise carry out the plan. Prefer existing functions and patterns over new machinery.
100
+
101
+ The tool catalog stays the same across modes for request-cache stability. These plan-mode rules override any later tool description or guidance that suggests using mutation tools; those tools remain listed to keep the tool catalog unchanged. Do not use todo_write to track this planning phase: it tracks implementation after an approved plan, while the plan itself belongs in exit_plan_mode.
102
+
103
+ Resolve discoverable facts by inspection. Use ask_user_question only for user-owned choices or material ambiguity that inspection cannot answer. Do not ask the user where code lives or how current behavior works when you can find out.
104
+
105
+ Make the plan decision-complete: state the goal and success criteria; group implementation changes by subsystem; identify public API, schema, and data-flow changes; cover edge cases, failure modes, tests, acceptance criteria, and explicit assumptions. Keep it concise enough to review but detailed enough that another engineer can implement it without making design decisions.
106
+
107
+ When ready, call exit_plan_mode with the complete plan markdown, starting with a # title. Make exit_plan_mode the only and final tool call in that assistant response: it presents the plan for approval, and implementation begins only in a later step after approval. Do not paste the final plan as a plain reply or ask "should I proceed?" through prose or ask_user_question. If review rejects it, incorporate the feedback and present again. If the review channel is unavailable or aborted, stay in plan mode and ask the user to switch modes manually; do not proceed with implementation.
108
+ - id: compaction
109
+ name: cordis:group
110
+ group: true
111
+ isolate:
112
+ compaction: true
113
+ toolResultPruner: true
114
+ config:
115
+ - id: compaction-basic
116
+ name: '@deepseek-ai/dsh-compaction-basic'
117
+ - id: command-compact
118
+ name: '@deepseek-ai/dsh-command-compact'
119
+ - id: tool-result-pruner
120
+ name: '@deepseek-ai/dsh-compaction-tool-result-pruner'
121
+ config:
122
+ thresholdChars: 8192
123
+ headChars: 4096
124
+ tailChars: 1024
125
+ - id: delegation
126
+ name: cordis:group
127
+ group: true
128
+ isolate:
129
+ workflowEngine: true
130
+ config:
131
+ - id: tool-subagent-control
132
+ name: '@deepseek-ai/dsh-tool-subagent-control'
133
+ - id: tool-subagent-list-agents
134
+ name: '@deepseek-ai/dsh-tool-subagent-control/list-agents'
135
+ - id: tool-subagent
136
+ name: '@deepseek-ai/dsh-tool-subagent'
137
+ config:
138
+ provider: spawn
139
+ toolName: subagent
140
+ modelSelectionSettings: true
141
+ - id: tool-subagent-fork
142
+ name: '@deepseek-ai/dsh-tool-subagent'
143
+ config:
144
+ provider: fork
145
+ toolName: subagent_fork
146
+ - id: workflow-ptc
147
+ name: '@deepseek-ai/dsh-workflow-ptc'
148
+ config:
149
+ provider: spawn
150
+ - id: tool-workflow
151
+ name: '@deepseek-ai/dsh-tool-workflow'
152
+ - id: tool-ask-user
153
+ name: '@deepseek-ai/dsh-tool-ask-user'
154
+ - id: tool-todo
155
+ name: '@deepseek-ai/dsh-tool-todo'
156
+ config:
157
+ allowParallelInProgress: true
158
+ - id: tool-web
159
+ name: '@deepseek-ai/dsh-tool-web'
160
+ config:
161
+ fetch: true
162
+ searchTimeoutMs: 60000
163
+ - id: present
164
+ name: '@deepseek-ai/dsh-tool-present'
165
+ - id: tool-plugin-manager
166
+ name: '@deepseek-ai/dsh-plugin-manager/tools'
167
+ disabled: true
168
+ - id: tool-plugin-market
169
+ name: '@deepseek-ai/dsh-plugin-market/tools'
170
+ disabled: true
package/lib/index.js ADDED
@@ -0,0 +1,197 @@
1
+ /**
2
+ * dsh-lead-mode host half.
3
+ *
4
+ * Three jobs: register the `lead-mode` runtime skill, register the `/lead-mode`
5
+ * slash command, and warn at startup when the Team runtime is absent.
6
+ *
7
+ * The plugin declares no `inject` of its own. Each surface waits for its own
8
+ * service through `ctx.inject()`, so a host missing `dsh-skill` still mounts the
9
+ * row and still gets the command. That is why registration is not guarded by a
10
+ * one-shot `ctx.get()`: a plain null check at apply time would lose the surface
11
+ * for good if the service fiber activates later in the boot order.
12
+ *
13
+ * @module dsh-lead-mode
14
+ */
15
+ import { readFileSync } from 'node:fs'
16
+ import { fileURLToPath } from 'node:url'
17
+
18
+ /** Cordis plugin name. */
19
+ export const name = 'lead-mode'
20
+
21
+ /** Profile package that provides the Team runtime, pinned to the rc.3 line. */
22
+ const TEAM_PROFILE_PACKAGE = '@deepseek-ai/dsh-experimental-agent-team-profile@0.2.1-rc.3'
23
+
24
+ /** Install command shown in every reminder. */
25
+ const ENABLE_COMMAND = `dsh plugin --profile <你的 profile 名> add ${TEAM_PROFILE_PACKAGE}`
26
+
27
+ /** Why the version pin matters, repeated wherever the command appears. */
28
+ const VERSION_NOTE = '不带版本号会装到 0.1.5-alpha.2,和 0.2.1 宿主对不上。'
29
+
30
+ /** Absolute path of the bundled skill body. */
31
+ const SKILL_URL = new URL('../skills/lead-mode/SKILL.md', import.meta.url)
32
+
33
+ /** Skill name shared by the file on disk, the runtime registration, and the naming manifest. */
34
+ const SKILL_NAME = 'lead-mode'
35
+
36
+ /** Command name shared by the registration and the naming manifest. */
37
+ const COMMAND_NAME = 'lead-mode'
38
+
39
+ /** Preset id declared in `cordis.patch.yml`. */
40
+ const PRESET_ID = 'lead-mode'
41
+
42
+ /**
43
+ * Read the bundled skill file and split off its YAML frontmatter.
44
+ *
45
+ * The runtime skill registry wants `description` as its own field, so the body
46
+ * handed to it must not repeat the frontmatter block. Reading synchronously
47
+ * keeps `apply` synchronous; the file is a few kilobytes shipped inside this
48
+ * package, so there is no I/O worth deferring.
49
+ *
50
+ * @returns the frontmatter description and the markdown body.
51
+ */
52
+ function readBundledSkill() {
53
+ const path = fileURLToPath(SKILL_URL)
54
+ const raw = readFileSync(path, 'utf8')
55
+ const match = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/.exec(raw)
56
+ if (match === null) throw new Error(`${path} has no YAML frontmatter`)
57
+ const description = /^description:\s*(.+)$/m.exec(match[1])
58
+ if (description === null) throw new Error(`${path} frontmatter has no description`)
59
+ const content = raw.slice(match[0].length).trim()
60
+ if (content.length === 0) throw new Error(`${path} has an empty body`)
61
+ return { description: description[1].trim(), content, path }
62
+ }
63
+
64
+ /**
65
+ * Report whether the Team runtime is mounted.
66
+ *
67
+ * `agentTeams` is provided by `@deepseek-ai/dsh-experimental-agent-team`. Its
68
+ * absence is the normal state for a host that never installed the official
69
+ * profile package, so the check reads without throwing.
70
+ *
71
+ * @param ctx - a context that can resolve host services.
72
+ * @returns the mount state and, when present, the configured member cap.
73
+ */
74
+ function teamRuntimeState(ctx) {
75
+ const agentTeams = ctx.get('agentTeams')
76
+ if (agentTeams === undefined) return { mounted: false }
77
+ return { mounted: true, maxMembers: agentTeams.config?.maxMembers }
78
+ }
79
+
80
+ /**
81
+ * Report whether the `lead-mode` preset reached the preset registry.
82
+ *
83
+ * The preset row lives in `cordis.patch.yml`; reading the registry back turns a
84
+ * broken row into a diagnostic instead of a silent no-op. An absent registry
85
+ * reports as `unknown` rather than `missing`, because this plugin cannot tell
86
+ * the two apart from here.
87
+ *
88
+ * @param ctx - a context that can resolve host services.
89
+ * @returns `present`, `missing`, or `unknown`.
90
+ */
91
+ async function presetState(ctx) {
92
+ const registry = ctx.get('agentPresets')
93
+ if (registry === undefined) return 'unknown'
94
+ const presets = await registry.list()
95
+ return presets.some((preset) => preset.id === PRESET_ID) ? 'present' : 'missing'
96
+ }
97
+
98
+ /**
99
+ * Render the preset state as the sentence the command output uses.
100
+ *
101
+ * @param state - a value returned by `presetState`.
102
+ * @returns one Chinese sentence.
103
+ */
104
+ function describePreset(state) {
105
+ if (state === 'present') return '已注册'
106
+ if (state === 'missing') return '未注册(cordis.patch.yml 里的 lead-mode 预设行没有生效)'
107
+ return '查不到(agentPresets 服务不在)'
108
+ }
109
+
110
+ /**
111
+ * Build the `/lead-mode` report.
112
+ *
113
+ * @param ctx - a context that can resolve host services.
114
+ * @returns a command result reporting dependency state and the install command.
115
+ */
116
+ async function report(ctx) {
117
+ const team = teamRuntimeState(ctx)
118
+ const preset = await presetState(ctx)
119
+ const lines = []
120
+
121
+ if (team.mounted) {
122
+ const cap = team.maxMembers === undefined ? '' : `(maxMembers ${team.maxMembers})`
123
+ lines.push(`Team 运行时:已挂载${cap}`)
124
+ } else {
125
+ lines.push('Team 运行时:未挂载')
126
+ }
127
+ lines.push(`lead-mode 预设:${describePreset(preset)}`)
128
+
129
+ if (team.mounted && preset === 'present') {
130
+ lines.push('')
131
+ lines.push('依赖齐了。切到 Lead 模式这个预设就能派活。')
132
+ return { kind: 'success', text: lines.join('\n') }
133
+ }
134
+
135
+ lines.push('')
136
+ if (!team.mounted) {
137
+ lines.push('缺 Team 运行时。装官方 profile 包:')
138
+ lines.push('')
139
+ lines.push(` ${ENABLE_COMMAND}`)
140
+ lines.push('')
141
+ lines.push(`${VERSION_NOTE}装完重启 dsh。`)
142
+ }
143
+ if (preset === 'missing') {
144
+ lines.push('lead-mode 预设行没生效。检查 dsh 是否把这个包加进了 profile 的 bundle 列表。')
145
+ }
146
+ return { kind: 'error', text: lines.join('\n') }
147
+ }
148
+
149
+ /**
150
+ * Register the skill, the command, and the startup check.
151
+ *
152
+ * @param ctx - the plugin context.
153
+ */
154
+ export function apply(ctx) {
155
+ const warn = (message) => ctx.logger.warn(message)
156
+
157
+ ctx.inject(['skills'], (skillsCtx) => {
158
+ let skill
159
+ try {
160
+ skill = readBundledSkill()
161
+ } catch (error) {
162
+ warn(`[lead-mode] 读不到 skills/lead-mode/SKILL.md,lead-mode skill 没注册:${String(error)}`)
163
+ return
164
+ }
165
+ skillsCtx.skills.register({
166
+ name: SKILL_NAME,
167
+ description: skill.description,
168
+ content: skill.content,
169
+ // `source` is required by the registry's load-time validation but is NOT
170
+ // defaulted by `register()`: `validateRuntimeSkill` (register) checks only
171
+ // name, description and invocation, while `validateDefinition` (load)
172
+ // throws unless `source` is a string. Omitting it registers fine and then
173
+ // fails every `skill` tool call with `source must be a string`.
174
+ source: 'dsh-lead-mode/skills/lead-mode/SKILL.md',
175
+ path: skill.path,
176
+ invocation: { modelInvocable: true, userInvocable: true },
177
+ })
178
+ })
179
+
180
+ ctx.inject(['commands'], (commandsCtx) => {
181
+ commandsCtx.commands.register({
182
+ name: COMMAND_NAME,
183
+ description: '检查 Lead 模式依赖是否就绪',
184
+ handler: () => report(commandsCtx),
185
+ })
186
+ })
187
+
188
+ if (ctx.get('skills') === undefined) {
189
+ warn('[lead-mode] skills 服务不在,lead-mode skill 暂时没注册。它会等 dsh-skill 挂载后再注册;一直不出现就检查 dsh-skill 是否装好。')
190
+ }
191
+ if (ctx.get('commands') === undefined) {
192
+ warn('[lead-mode] commands 服务不在,/lead-mode 命令暂时没注册。它会等 dsh-commands 挂载后再注册。')
193
+ }
194
+ if (ctx.get('agentTeams') === undefined) {
195
+ warn(`[lead-mode] 没检测到 Team 运行时(agentTeams 服务)。Lead 模式能切,但派不了活。装官方 profile 包:${ENABLE_COMMAND}。${VERSION_NOTE}`)
196
+ }
197
+ }
package/package.json CHANGED
@@ -1,6 +1,51 @@
1
1
  {
2
2
  "name": "dsh-lead-mode",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "description": "Lead 模式:一个 agent 预设、一个 skill、两条依赖提醒。预设与官方 standard 的差异只有 persona 一处。",
5
+ "type": "module",
6
+ "main": "lib/index.js",
7
+ "exports": {
8
+ ".": "./lib/index.js",
9
+ "./package.json": "./package.json"
10
+ },
11
+ "files": [
12
+ "lib",
13
+ "skills",
14
+ "cordis.patch.yml",
15
+ "README.md",
16
+ "README.en.md",
17
+ "LICENSE"
18
+ ],
19
+ "engines": {
20
+ "node": ">=20",
21
+ "dsh": ">=0.2.1-rc.2"
22
+ },
23
+ "dshTarget": "0.2.1-rc.3",
24
+ "dsh": {
25
+ "bundle": {
26
+ "patch": "./cordis.patch.yml"
27
+ }
28
+ },
29
+ "keywords": [
30
+ "deepseek-harness",
31
+ "dsh",
32
+ "dsh-plugin",
33
+ "dshtag",
34
+ "agent-teams",
35
+ "agent-preset",
36
+ "lead-mode"
37
+ ],
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "git+https://github.com/xiebaiyuan/dsh-lead-mode.git"
41
+ },
42
+ "license": "MIT",
43
+ "peerDependencies": {
44
+ "@deepseek-ai/cordis": "^4.0.5",
45
+ "@deepseek-ai/dsh": ">=0.2.1-rc.2",
46
+ "@deepseek-ai/schemastery": "^3.18.5",
47
+ "@deepseek-ai/dsh-agent-preset-registry": ">=0.2.1-rc.2",
48
+ "@deepseek-ai/dsh-skill": ">=0.2.1-rc.2",
49
+ "@deepseek-ai/dsh-commands": ">=0.2.1-rc.2"
50
+ }
51
+ }
@@ -0,0 +1,88 @@
1
+ ---
2
+ name: lead-mode
3
+ description: Lead 工作法。当你要拆活、派活给 teammate、用共享任务板协作,或验收多路并行产出时用。
4
+ ---
5
+
6
+ # Lead 工作法
7
+
8
+ 你是 Lead。你拆活、派活、验收。动手的活尽量派出去,别自己一个人干完。
9
+
10
+ ## 开工先确认能不能派活
11
+
12
+ 检查本会话有没有这些工具:`spawn_teammate`、`send_message`、`list_agents`、`wait_agent`、`team_task_create`、`team_task_update`。
13
+
14
+ 没有就停下。只做一件事:让用户去开 dsh 官方 Agent Teams,命令是
15
+
16
+ ```
17
+ dsh plugin --profile <你的 profile 名> add @deepseek-ai/dsh-experimental-agent-team-profile@0.2.1-rc.3
18
+ ```
19
+
20
+ 不带版本号会装到 0.1.5-alpha.2,和 0.2.1 宿主对不上。
21
+
22
+ 不要自己硬干,也不要假装能派活。
23
+
24
+ ## 开工前对齐三件事
25
+
26
+ 派活之前先把这三件事写清楚,用户点头再动手:
27
+
28
+ 1. 目标是什么。
29
+ 2. 这次改动动哪些东西。
30
+ 3. 什么叫完成。写成能判定的验收标准,不要写「跑通就行」。
31
+
32
+ 目标或指令有疑问先问用户。别自己挑一个解释就开始干。
33
+
34
+ ## 派活必须自包含
35
+
36
+ teammate 看不到你的上下文。它能看到的只有你写的那段 prompt。
37
+
38
+ 派活时把这些写全:
39
+
40
+ - 目标、约束、验收标准
41
+ - 已知的失败现象和报错原文
42
+ - 相关文件路径,用绝对路径
43
+ - 环境坑,比如本机 `diff` 是坏的要用 `/usr/bin/diff`
44
+
45
+ 派活 prompt 里写「按刚才说的做」等于没派。它不知道「刚才」。
46
+
47
+ ## 写作用域不重叠
48
+
49
+ 两个 teammate 同时改一个文件,改动会互相覆盖,而且谁都发现不了。
50
+
51
+ 派活前先分好文件归属,一人一块。分不开的活排成依赖,用 `team_task_create` 的 `blocked_by` 串起来。
52
+
53
+ 写作用域有重叠时,在 task 描述里写明重叠在哪、谁先谁后。别指望 teammate 自己协调。
54
+
55
+ ## 共享任务流程
56
+
57
+ 每个活都是一个共享任务。流程固定:
58
+
59
+ 1. `team_task_list` 看有哪些活、哪个 ready。
60
+ 2. `team_task_get` 读完整规格。
61
+ 3. `team_task_update` 带当前 `revision` 执行 `claim`。
62
+ 4. 干活。
63
+ 5. `team_task_update` 用最新 `revision` 执行 `complete`。
64
+
65
+ `revision` 不对就是有人在你之前改过这条 task。重新 `get` 一次再操作,别硬顶。
66
+
67
+ task 描述就是完整规格。规格写细一点,teammate 少问一轮。
68
+
69
+ ## 等 teammate 的规矩
70
+
71
+ `wait_agent` 前先 `list_agents`,确认有人正在 running。没人在跑,`wait_agent` 立刻返回 noProgress,白等。
72
+
73
+ 没人在跑就先 `send_message` 唤醒,再等。
74
+
75
+ `inactive` 只说明当前没有 turn 在执行,不代表活干完了、也不代表失败。看 task 状态判断。
76
+
77
+ ## 给最终答复前
78
+
79
+ - 必需的 teammate 都等齐了再答。没等齐就说「还在跑」,别把半成品当结论。
80
+ - 最终验证自己做:跑测试、看 diff、核数字。不要只信 teammate 的回报。
81
+ - 回报里有「已通过」「已修复」这类话,去核证据。核不到就写「未验证」。
82
+ - 偏离规格的地方单独列出来,别混在成功清单里。
83
+
84
+ ## 回报怎么写
85
+
86
+ 结论在前。文件清单、验收输出、偏离规格三块分开。
87
+
88
+ 没实测的数字不写精确值。不知道就写「未验证」。