dsh-tower 0.0.0-stage → 1.1.1
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 +72 -0
- package/LICENSE +21 -0
- package/README.md +165 -2
- package/README.zh.md +166 -0
- package/cordis.patch.yml +23 -0
- package/icon.svg +7 -0
- package/index.js +296 -0
- package/lib/git.js +144 -0
- package/lib/modeStore.js +68 -0
- package/lib/store.js +123 -0
- package/lib/tools.js +801 -0
- package/lib/tower.js +1507 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +53 -4
- package/worker.js +41 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 1.1.1 — 2026-10-18
|
|
4
|
+
|
|
5
|
+
- README(英文/中文)与 dsh-plugin 提交信息中注明:Tower 模式的灵感来自 **Kimi Code**
|
|
6
|
+
(Moonshot AI)的实验性 Tower 模式;本项目是面向 DSH 的独立实现,不包含 Kimi Code 源码,
|
|
7
|
+
与 Moonshot AI 无隶属关系。
|
|
8
|
+
- 无运行时行为变化。
|
|
9
|
+
|
|
10
|
+
## 1.1.0 — 2026-10-18
|
|
11
|
+
|
|
12
|
+
- **包名改为 `dsh-tower`**:Host 插件名、`tower-worker` preset 插件名、`cordis.patch.yml`、
|
|
13
|
+
可选 UI 包(`dsh-tower-ui`)与中英文 README 全部同步改名;移除 `package.json` 的 `private` 字段。
|
|
14
|
+
- **`dsh-tower@1.1.0` 已发布到 npm**(首次发布审核已通过):`dsh plugin --profile web add dsh-tower`
|
|
15
|
+
即可安装并可进入 DSH 插件中心;同时保留 `github:louifinn/dsh-tower` 源码安装与本地 checkout 链接。
|
|
16
|
+
- 已安装 `@local/dsh-tower` 的用户需要 `remove_bundle` 后重新安装 `dsh-tower`;配置项 `id: tower`
|
|
17
|
+
与 config 内容不变,运行行为无变化。
|
|
18
|
+
|
|
19
|
+
## 1.0.5 — 2026-10-18
|
|
20
|
+
|
|
21
|
+
- README 增加源码安装命令 `dsh plugin --profile web add github:louifinn/dsh-tower`,满足
|
|
22
|
+
dsh-plugin.org 的收录要求(公开仓库 + `dsh-plugin` topic + README 安装命令 + 根 package.json)。
|
|
23
|
+
- 无运行时行为变化。
|
|
24
|
+
|
|
25
|
+
## 1.0.4 — 2026-10-18
|
|
26
|
+
|
|
27
|
+
- 版权署名统一为 **Loui Finn**:`LICENSE`、`README.md`、`README.zh.md` 与 `package.json` 的 author。
|
|
28
|
+
- 无运行时行为变化。
|
|
29
|
+
|
|
30
|
+
## 1.0.3 — 2026-10-18
|
|
31
|
+
|
|
32
|
+
- 开源前整理:README 改为英文主文档(中文版保留在 `README.zh.md`),补充特性、安装、安全约束、
|
|
33
|
+
工作原理、排障与贡献说明;添加 CI/许可证徽章与 “powered by dsh” 徽章。
|
|
34
|
+
- `tests/README.md`、`ui-bundle/README.md` 改为英文并去掉与特定会话绑定的表述。
|
|
35
|
+
- 新增 `CONTRIBUTING.md`、`SECURITY.md`;`.gitignore` 增加 `.env`/密钥/覆盖率等防泄漏规则。
|
|
36
|
+
- `package.json` 补充 repository/homepage/bugs/keywords 元数据。
|
|
37
|
+
- 清理提交作者邮箱:历史提交改用 GitHub noreply 地址重新发布。
|
|
38
|
+
- 无运行时行为变化。
|
|
39
|
+
|
|
40
|
+
## 1.0.2 — 2026-10-18
|
|
41
|
+
|
|
42
|
+
- **仓库布局改为符合 DSH 插件规范**:仓库根目录即 bundle 包根目录,`package.json`(含
|
|
43
|
+
`dsh.bundle.patch`)与 `cordis.patch.yml` 都在根目录;原先的 `bundle/` 子目录已移除。
|
|
44
|
+
- `package.json` 合并了插件包声明(name/version/exports/files/dsh)与开发脚本(`npm test`)。
|
|
45
|
+
- 测试与文档中的相对路径同步更新(`../bundle/...` → `../...`),README 更新为插件包说明。
|
|
46
|
+
- 无运行时行为变化。
|
|
47
|
+
|
|
48
|
+
## 1.0.1 — 2026-10-18
|
|
49
|
+
|
|
50
|
+
- **修复:`/tower <指令>` 会把一条没有 `role` 的消息写入会话,导致后续模型请求 422
|
|
51
|
+
`messages[N]: missing field role`(会话表现为“损坏”)。** `agent.steer` 需要完整的
|
|
52
|
+
`UserMessage`(`id` + `role` + `content` + `source`),不是 `{content, source}` 初始化对象;
|
|
53
|
+
转发时改为本地构造完整消息(`randomUUID()` 作为 id),与 `createUserMessage()` 的形状一致。
|
|
54
|
+
- 新增回归测试:mock 上下文断言转发消息带 `role:"user"` 与唯一 `id`;
|
|
55
|
+
隔离 Web 运行时用 `/tower 这是一条测试消息` 实测模型正常回复,会话日志中 spliced/user/message
|
|
56
|
+
均带 `role`/`id`。
|
|
57
|
+
- 提供 `tests/live/repair-session.cjs`:可修复已被旧版本写坏的会话日志(补 `role`/`id`,
|
|
58
|
+
原子写 + 备份 + 生成验证副本)。
|
|
59
|
+
|
|
60
|
+
## 1.0.0 — 2026-10-18
|
|
61
|
+
|
|
62
|
+
- `/tower` 命令支持裸调用、`on`/`off`、以及携带用户指令(`/tower on 继续`、`/tower off 继续`、`/tower 继续`);指令与附件通过 `agent.steer` 转发。
|
|
63
|
+
- 新增 `allowAgentControl` 配置:开启后模型可通过 `tower_control` 自行进出模式,必须给出理由。
|
|
64
|
+
- 进入模式时通过 `ctx.goals.pause` 暂停活跃 goal,并在结果中提示用户自行恢复。
|
|
65
|
+
- 模式持久化到 `$DSH_HOME/tower-mode/modes.json`(原子写、保留 200 条)。
|
|
66
|
+
- 移除 P6 验收用的临时 `tower_mode_dev` 钩子。
|
|
67
|
+
- 新增 README、单元测试、协议 e2e 测试与 opt-in UI bundle。
|
|
68
|
+
- 版本从 0.1.0 提升到 1.0.0。
|
|
69
|
+
|
|
70
|
+
## 0.1.0 — 2026-10-17
|
|
71
|
+
|
|
72
|
+
- 首个可用版本:P1–P6(mission/worktree/spawn/inbox/review/merge/rebase/teardown/mode)。
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Loui Finn
|
|
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.md
CHANGED
|
@@ -1,3 +1,166 @@
|
|
|
1
|
-
#
|
|
1
|
+
# dsh-tower
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://github.com/louifinn/dsh-tower/actions/workflows/test.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/dsh-tower)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[中文说明](README.zh.md)
|
|
7
|
+
|
|
8
|
+
**Tower** is a multi-agent orchestration plugin for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (DSH). It turns one agent session into a small engineering team: the session acts as the *control tower*, worker agents do the implementation inside isolated Git worktrees, and nothing reaches your base branch without an independent review and a hard merge gate.
|
|
9
|
+
|
|
10
|
+
Tower mode and its mission/review workflow are inspired by the experimental **Tower mode in [Kimi Code](https://www.kimi.com/code)** by Moonshot AI. This is an independent implementation for DSH and is not affiliated with Moonshot AI; see [Acknowledgements](#acknowledgements).
|
|
11
|
+
|
|
12
|
+
The repository root **is** the DSH bundle: `package.json` declares `dsh.bundle.patch` and `cordis.patch.yml` lives at the root, as the DSH plugin specification expects.
|
|
13
|
+
|
|
14
|
+
## Features
|
|
15
|
+
|
|
16
|
+
- **Human-owned Tower mode.** `/tower` toggles a session-level stance that narrows the tool surface and injects the Tower protocol. `/tower on|off <instruction>` also forwards your instruction to the model in the same step.
|
|
17
|
+
- **Missions with real isolation.** Every mission gets its own branch and Git worktree; workers never touch your checkout.
|
|
18
|
+
- **Review-gated merges.** A reviewer bound to the current branch tip must submit a `clean` / `merge` verdict; the merge gate re-checks scope, staleness, task completion, review history, and worktree ownership before a `--no-ff` merge.
|
|
19
|
+
- **Durable coordination.** Roster, inbox, findings, reviews, and mission state are persisted under `.git/dsh-tower/`, so a restart does not lose the plan.
|
|
20
|
+
- **Safe by default.** While Tower mode is active, `create_goal`, `update_goal(resume)`, `todo_write`, the Team task board, and `spawn_teammate` are refused; a paused goal is never resumed automatically.
|
|
21
|
+
|
|
22
|
+
## Requirements
|
|
23
|
+
|
|
24
|
+
- DeepSeek Harness `0.2.1-rc.2` (or a compatible newer build)
|
|
25
|
+
- Node.js 22 or newer
|
|
26
|
+
- Git (worktrees are created locally; no network access is required)
|
|
27
|
+
|
|
28
|
+
## Install
|
|
29
|
+
|
|
30
|
+
Install the published package into a DSH profile:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
dsh plugin --profile web add dsh-tower
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Inside DSH you can use the plugin manager with the same target:
|
|
37
|
+
|
|
38
|
+
```text
|
|
39
|
+
plugin_manager({ action: "install_bundle", target: "dsh-tower" })
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
For development, install from GitHub or link a local checkout:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
dsh plugin --profile web add github:louifinn/dsh-tower
|
|
46
|
+
dsh plugin --profile <profile> add <absolute path to this repository>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The Host plugin is loaded when the DSH process starts, so **restart DSH after installing or updating**. Remove it with `remove_bundle` and the package name `dsh-tower`.
|
|
50
|
+
|
|
51
|
+
## Quick start
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
/tower on
|
|
55
|
+
|
|
56
|
+
tower_init <repoRoot>
|
|
57
|
+
tower_plan <repoRoot> missions=[...]
|
|
58
|
+
tower_spawn <repoRoot> missionId=M1 role=worker
|
|
59
|
+
# worker implements and reports completion
|
|
60
|
+
tower_preflight <repoRoot> missionId=M1 # must be green before merging
|
|
61
|
+
tower_spawn <repoRoot> missionId=M1 role=reviewer
|
|
62
|
+
tower_review ... # reviewer submits verdict
|
|
63
|
+
tower_preflight <repoRoot> missionId=M1
|
|
64
|
+
tower_merge <repoRoot> missionId=M1
|
|
65
|
+
tower_teardown <repoRoot>
|
|
66
|
+
|
|
67
|
+
/tower off
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
A typical run takes one worker mission and one reviewer round for a small change.
|
|
71
|
+
|
|
72
|
+
## Commands
|
|
73
|
+
|
|
74
|
+
| Input | Behavior |
|
|
75
|
+
|---|---|
|
|
76
|
+
| `/tower` | Enter Tower mode (stays on if already on) |
|
|
77
|
+
| `/tower on` | Enter or stay |
|
|
78
|
+
| `/tower on <instruction>` | Enter/stay **and** forward `<instruction>` as the next user message |
|
|
79
|
+
| `/tower off` | Leave Tower mode |
|
|
80
|
+
| `/tower off <instruction>` | Leave **and** forward `<instruction>` |
|
|
81
|
+
| `/tower <instruction>` | Ensure on, then forward `<instruction>` |
|
|
82
|
+
|
|
83
|
+
Image and file attachments are forwarded together with the instruction as one complete `UserMessage`.
|
|
84
|
+
|
|
85
|
+
## Configuration
|
|
86
|
+
|
|
87
|
+
```yaml
|
|
88
|
+
- id: tower
|
|
89
|
+
name: 'dsh-tower'
|
|
90
|
+
config:
|
|
91
|
+
section: 'Optional replacement for the Tower-mode system prompt text'
|
|
92
|
+
allowAgentControl: true # true registers tower_control; false makes the mode human-only
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
- `allowAgentControl` defaults to `false` in code. The bundled `cordis.patch.yml` enables it (`true`) so the model may enter/leave Tower mode when the user intent or task state clearly warrants it, always stating a reason.
|
|
96
|
+
- When disabled, only the human can change the mode.
|
|
97
|
+
|
|
98
|
+
## Tools (17)
|
|
99
|
+
|
|
100
|
+
`tower_init` · `tower_plan` · `tower_mission` · `tower_status` · `tower_spawn` · `tower_roster` · `tower_adopt` · `tower_send` · `tower_inbox` · `tower_complete` · `tower_finding` · `tower_review` · `tower_preflight` · `tower_merge` · `tower_rebase` · `tower_teardown` · `tower_mode`
|
|
101
|
+
|
|
102
|
+
`tower_control` exists only when `allowAgentControl: true`.
|
|
103
|
+
|
|
104
|
+
## Safety and guardrails
|
|
105
|
+
|
|
106
|
+
- **No merge without a green gate.** `tower_preflight` is read-only and reports stable blocker codes; `tower_merge` refuses when any blocker remains.
|
|
107
|
+
- **Review is bound to a commit.** If the branch tip moves after a review, the gate reports `tip-moved`; re-review is required (a clean rebase waiver is the only exception).
|
|
108
|
+
- **Scope enforcement.** A mission may only change files matched by its declared scope globs; `out-of-scope` blocks the merge.
|
|
109
|
+
- **Worktree ownership.** Dirty worktrees, a running worker, or a branch owned by a closed mission block teardown/merge.
|
|
110
|
+
- **Goal isolation.** Entering Tower mode pauses the active goal and records it; leaving does not resume it. Use `/tower off` and resume the goal yourself.
|
|
111
|
+
|
|
112
|
+
The 13 stable blocker codes are: `branch-missing`, `deps-unmerged`, `read-only-survey`, `stale-base`, `no-review`, `review-hold`, `not-clean`, `review-not-approved`, `tip-moved`, `review-mission-mismatch`, `out-of-scope`, `base-dirty`, `branch-owned-by-closed-missions` (plus mission/worker guards).
|
|
113
|
+
|
|
114
|
+
## How it works
|
|
115
|
+
|
|
116
|
+
A mission moves through `planned → active → completed → merged` (or `blocked` / `paused` / `abandoned`). State lives in `<git-common-dir>/dsh-tower/`:
|
|
117
|
+
|
|
118
|
+
| Path | Contents |
|
|
119
|
+
|---|---|
|
|
120
|
+
| `.git/dsh-tower/state.json` | missions, roster, reviews, findings, inbox |
|
|
121
|
+
| `.git/dsh-tower/activity.jsonl` | append-only activity log |
|
|
122
|
+
| `<checkout parent>/.dsh-tower-worktrees/<hash>/<missionId>` | per-mission worktree |
|
|
123
|
+
| `$DSH_HOME/tower-mode/modes.json` | Tower mode state per agent/session |
|
|
124
|
+
|
|
125
|
+
Workers and reviewers are ordinary DSH subagents started with the bundled `tower-worker` preset; their tools are restricted to the mission surface (filesystem, shell, and Tower protocol tools), never merge/spawn.
|
|
126
|
+
|
|
127
|
+
## Project layout
|
|
128
|
+
|
|
129
|
+
| Path | Contents |
|
|
130
|
+
|---|---|
|
|
131
|
+
| `package.json`, `cordis.patch.yml` | bundle manifest and loader patch (inserts the Host plugin and the `tower-worker` preset) |
|
|
132
|
+
| `index.js`, `lib/`, `worker.js` | Host entry, protocol implementation, worker preset policy |
|
|
133
|
+
| `locale/`, `icon.svg` | localization and icon |
|
|
134
|
+
| `tests/` | pure-function, protocol end-to-end, and plugin-level tests; optional isolated Web-runtime scripts |
|
|
135
|
+
| `ui-bundle/` | optional Client widget (static `/tower` hint), not installed by default |
|
|
136
|
+
| `.github/workflows/test.yml` | CI running the offline suite on Node 22/24 |
|
|
137
|
+
|
|
138
|
+
## Development and testing
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
npm test # node --test tests/*.test.mjs
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
The offline suite needs no DSH process and creates throwaway Git repositories in the OS temp directory. `tests/README.md` documents the isolated Web-runtime checks, model-driven acceptance, and the session-diagnostic scripts used while hardening the plugin.
|
|
145
|
+
|
|
146
|
+
## Troubleshooting
|
|
147
|
+
|
|
148
|
+
- **The plugin does not appear after install/update.** Host plugins load at DSH startup; restart DSH. Confirm the entry point targets this repository root (the folder with `package.json` and `cordis.patch.yml`), not a subdirectory.
|
|
149
|
+
- **`tower_control` is missing.** The config `allowAgentControl` is `false`; set it to `true` and restart.
|
|
150
|
+
- **Merge is blocked.** Run `tower_preflight` and read the blocker codes above; `stale-base` means run `tower_rebase` first.
|
|
151
|
+
- **A mission branch is stale after base moved.** `tower_rebase` rebases inside the worktree; a clean conflict-free rebase waives re-review for the previous verdict.
|
|
152
|
+
|
|
153
|
+
## Contributing
|
|
154
|
+
|
|
155
|
+
Issues and pull requests are welcome. Please run `npm test` before opening a PR; see [CONTRIBUTING.md](CONTRIBUTING.md) for details. Security reports: please avoid opening a public issue with exploit details; open a minimal issue asking for a private channel.
|
|
156
|
+
|
|
157
|
+
## Acknowledgements
|
|
158
|
+
|
|
159
|
+
- **Kimi Code (Moonshot AI)** — the Tower mode concept, including human-owned activation, an isolated Git worktree per mission, and the review-gated merge protocol, is inspired by the experimental Tower mode in [Kimi Code](https://www.kimi.com/code) ([source](https://github.com/MoonshotAI/kimi-code)). This project re-implements those ideas on top of DeepSeek Harness services; it contains no Kimi Code source code and is not affiliated with or endorsed by Moonshot AI.
|
|
160
|
+
- **DeepSeek Harness** — for the plugin, tool, session, and subagent APIs this project is built on.
|
|
161
|
+
|
|
162
|
+
## License
|
|
163
|
+
|
|
164
|
+
MIT © Loui Finn
|
|
165
|
+
|
|
166
|
+
[](https://github.com/deepseek-ai/deepseek-harness)
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# dsh-tower
|
|
2
|
+
|
|
3
|
+
[](https://github.com/louifinn/dsh-tower/actions/workflows/test.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/dsh-tower)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[English](README.md)
|
|
7
|
+
|
|
8
|
+
**Tower** 是 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)(DSH)的多代理编排插件。它把一个 agent 会话变成一个小型工程团队:会话本身是*控制塔*,worker agent 在隔离的 Git worktree 里实现任务,任何改动都必须经过独立审查和硬门禁才能合入基线分支。
|
|
9
|
+
|
|
10
|
+
Tower 模式与 mission/审查工作流的灵感来自 Moonshot AI 的 **Kimi Code** 中实验性的 Tower 模式([Kimi Code](https://www.kimi.com/code))。本项目是面向 DSH 的独立实现,与 Moonshot AI 无隶属关系;详见[致谢](#致谢)。
|
|
11
|
+
|
|
12
|
+
仓库根目录**就是** DSH bundle 包根:`package.json` 声明 `dsh.bundle.patch`,`cordis.patch.yml` 位于根目录,符合 DSH 插件规范。
|
|
13
|
+
|
|
14
|
+
## 特性
|
|
15
|
+
|
|
16
|
+
- **由人类掌握的 Tower 模式。** `/tower` 切换会话级模式:收窄工具面并注入 Tower 协议;`/tower on|off <指令>` 还能把指令作为下一步用户消息转发给模型。
|
|
17
|
+
- **任务级隔离。** 每个 mission 使用独立分支和 Git worktree,worker 不会碰到你的主检出。
|
|
18
|
+
- **审查门禁合并。** 审查者必须针对当前分支 tip 给出 `clean` / `merge` 结论;合并门禁重新校验 scope、分支新鲜度、任务完成度、审查记录与 worktree 归属,通过后才执行 `--no-ff` 合并。
|
|
19
|
+
- **可恢复的协作状态。** roster、inbox、findings、reviews 与 mission 状态持久化在 `.git/dsh-tower/` 下,重启不会丢计划。
|
|
20
|
+
- **默认安全。** Tower 模式开启期间拒绝 `create_goal`、`update_goal(resume)`、`todo_write`、Team 任务板与 `spawn_teammate`;被暂停的 goal 不会被自动恢复。
|
|
21
|
+
|
|
22
|
+
## 环境要求
|
|
23
|
+
|
|
24
|
+
- DeepSeek Harness `0.2.1-rc.2`(或兼容的新版本)
|
|
25
|
+
- Node.js 22+
|
|
26
|
+
- Git(worktree 在本地创建,不需要联网)
|
|
27
|
+
|
|
28
|
+
## 安装
|
|
29
|
+
|
|
30
|
+
把已发布的包安装到 DSH profile:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
dsh plugin --profile web add dsh-tower
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
在 DSH 中也可以用插件管理器指定同一目标:
|
|
37
|
+
|
|
38
|
+
```text
|
|
39
|
+
plugin_manager({ action: "install_bundle", target: "dsh-tower" })
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
开发时改为从 GitHub 安装或链接本地 checkout:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
dsh plugin --profile web add github:louifinn/dsh-tower
|
|
46
|
+
dsh plugin --profile <profile> add <本仓库的绝对路径>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Host 插件在 DSH 进程启动时加载,**安装或更新后需重启 DSH**。卸载使用 `remove_bundle`,包名 `dsh-tower`。
|
|
50
|
+
|
|
51
|
+
## 快速开始
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
/tower on
|
|
55
|
+
|
|
56
|
+
tower_init <repoRoot>
|
|
57
|
+
tower_plan <repoRoot> missions=[...]
|
|
58
|
+
tower_spawn <repoRoot> missionId=M1 role=worker
|
|
59
|
+
# worker 实现并汇报完成
|
|
60
|
+
tower_preflight <repoRoot> missionId=M1 # 必须全绿才能合并
|
|
61
|
+
tower_spawn <repoRoot> missionId=M1 role=reviewer
|
|
62
|
+
tower_review ... # 审查者提交结论
|
|
63
|
+
tower_preflight <repoRoot> missionId=M1
|
|
64
|
+
tower_merge <repoRoot> missionId=M1
|
|
65
|
+
tower_teardown <repoRoot>
|
|
66
|
+
|
|
67
|
+
/tower off
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
小改动通常一轮 worker + 一轮 reviewer 即可完成。
|
|
71
|
+
|
|
72
|
+
## 命令
|
|
73
|
+
|
|
74
|
+
| 输入 | 行为 |
|
|
75
|
+
|---|---|
|
|
76
|
+
| `/tower` | 开启 Tower 模式(已开启则保持) |
|
|
77
|
+
| `/tower on` | 开启或保持 |
|
|
78
|
+
| `/tower on <指令>` | 开启/保持,并把 `<指令>` 作为下一条用户消息转发 |
|
|
79
|
+
| `/tower off` | 退出 Tower 模式 |
|
|
80
|
+
| `/tower off <指令>` | 退出并转发 `<指令>` |
|
|
81
|
+
| `/tower <指令>` | 确保开启,然后转发 `<指令>` |
|
|
82
|
+
|
|
83
|
+
图片与文件附件会随指令一起作为一条完整的 `UserMessage` 转发。
|
|
84
|
+
|
|
85
|
+
## 配置
|
|
86
|
+
|
|
87
|
+
```yaml
|
|
88
|
+
- id: tower
|
|
89
|
+
name: 'dsh-tower'
|
|
90
|
+
config:
|
|
91
|
+
section: '(可选)覆盖 Tower 模式系统提示文案'
|
|
92
|
+
allowAgentControl: true # true 时注册 tower_control;false 时只有人类能切换
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
- 代码中 `allowAgentControl` 默认 `false`;仓库自带的 `cordis.patch.yml` 把它设为 `true`:当用户意图或任务状态明确时,模型可以自行进出 Tower 模式,但必须给出理由。
|
|
96
|
+
- 设为 `false` 时只有人类能切换模式。
|
|
97
|
+
|
|
98
|
+
## 工具(17 个)
|
|
99
|
+
|
|
100
|
+
`tower_init` · `tower_plan` · `tower_mission` · `tower_status` · `tower_spawn` · `tower_roster` · `tower_adopt` · `tower_send` · `tower_inbox` · `tower_complete` · `tower_finding` · `tower_review` · `tower_preflight` · `tower_merge` · `tower_rebase` · `tower_teardown` · `tower_mode`
|
|
101
|
+
|
|
102
|
+
`tower_control` 仅在 `allowAgentControl: true` 时存在。
|
|
103
|
+
|
|
104
|
+
## 安全与约束
|
|
105
|
+
|
|
106
|
+
- **门禁不全绿不合并。** `tower_preflight` 是只读检查,返回稳定的 blocker code;存在 blocker 时 `tower_merge` 拒绝合并。
|
|
107
|
+
- **审查绑定提交。** 审查后分支 tip 变化会报 `tip-moved`,必须重新审查;唯一的例外是干净 rebase 的免审豁免。
|
|
108
|
+
- **scope 强制。** mission 只能修改其 scope glob 匹配的文件,越界会以 `out-of-scope` 阻止合并。
|
|
109
|
+
- **worktree 归属。** 脏工作树、运行中的 worker、已关闭 mission 的分支都会阻止合并或 teardown。
|
|
110
|
+
- **goal 隔离。** 进入 Tower 模式会暂停活跃 goal 并记录;退出不会自动恢复,需要你自行恢复。
|
|
111
|
+
|
|
112
|
+
13 个稳定 blocker code:`branch-missing`、`deps-unmerged`、`read-only-survey`、`stale-base`、`no-review`、`review-hold`、`not-clean`、`review-not-approved`、`tip-moved`、`review-mission-mismatch`、`out-of-scope`、`base-dirty`、`branch-owned-by-closed-missions`(另有 mission/worker 守卫)。
|
|
113
|
+
|
|
114
|
+
## 工作原理
|
|
115
|
+
|
|
116
|
+
mission 生命周期:`planned → active → completed → merged`(或 `blocked` / `paused` / `abandoned`)。状态位置:
|
|
117
|
+
|
|
118
|
+
| 路径 | 内容 |
|
|
119
|
+
|---|---|
|
|
120
|
+
| `.git/dsh-tower/state.json` | missions、roster、reviews、findings、inbox |
|
|
121
|
+
| `.git/dsh-tower/activity.jsonl` | 只追加的活动日志 |
|
|
122
|
+
| `<主检出父目录>/.dsh-tower-worktrees/<hash>/<missionId>` | 每个 mission 的 worktree |
|
|
123
|
+
| `$DSH_HOME/tower-mode/modes.json` | 每个 agent/session 的 Tower 模式状态 |
|
|
124
|
+
|
|
125
|
+
worker 与 reviewer 是使用内置 `tower-worker` preset 的普通 DSH 子代理;它们的工具被限制在 mission 允许面(文件系统、shell、Tower 协议工具),不包含 merge/spawn。
|
|
126
|
+
|
|
127
|
+
## 项目结构
|
|
128
|
+
|
|
129
|
+
| 路径 | 内容 |
|
|
130
|
+
|---|---|
|
|
131
|
+
| `package.json`、`cordis.patch.yml` | bundle 清单与 loader patch(插入 Host 插件和 `tower-worker` preset) |
|
|
132
|
+
| `index.js`、`lib/`、`worker.js` | Host 入口、协议实现、worker preset 策略 |
|
|
133
|
+
| `locale/`、`icon.svg` | 本地化与图标 |
|
|
134
|
+
| `tests/` | 纯函数、协议 e2e、插件级测试;可选的真实 Web 运行时脚本 |
|
|
135
|
+
| `ui-bundle/` | 可选 Client 小挂件(静态 `/tower` 提示),默认不安装 |
|
|
136
|
+
| `.github/workflows/test.yml` | CI:Node 22/24 上跑离线套件 |
|
|
137
|
+
|
|
138
|
+
## 开发与测试
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
npm test # node --test tests/*.test.mjs
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
离线套件不需要 DSH 进程,只在系统临时目录创建一次性 Git 仓库。隔离 Web 运行时检查、模型驱动验收和会话诊断脚本见 `tests/README.md`。
|
|
145
|
+
|
|
146
|
+
## 常见问题
|
|
147
|
+
|
|
148
|
+
- **安装/更新后插件不出现。** Host 插件在 DSH 启动时加载,请重启 DSH;并确认安装目标指向本仓库根目录(含 `package.json` 与 `cordis.patch.yml` 的那一层),而不是子目录。
|
|
149
|
+
- **没有 `tower_control`。** 配置 `allowAgentControl` 为 `false`;改为 `true` 并重启。
|
|
150
|
+
- **合并被阻止。** 运行 `tower_preflight` 查看 blocker code;`stale-base` 表示先执行 `tower_rebase`。
|
|
151
|
+
- **基线前进后分支过期。** `tower_rebase` 在 worktree 内完成 rebase;干净且无冲突的 rebase 可免去上一轮审查的重审。
|
|
152
|
+
|
|
153
|
+
## 贡献
|
|
154
|
+
|
|
155
|
+
欢迎 issue 与 pull request。提交 PR 前请先运行 `npm test`,细节见 [CONTRIBUTING.md](CONTRIBUTING.md)。安全相关问题请不要在公开 issue 里贴利用细节,先开一个最小化 issue 申请私下渠道。
|
|
156
|
+
|
|
157
|
+
## 致谢
|
|
158
|
+
|
|
159
|
+
- **Kimi Code(Moonshot AI)**:Tower 模式的整体概念——由人类开启的模式、每个 mission 独立 Git worktree、审查门禁合并协议——灵感来自 Kimi Code 的实验性 Tower 模式([官网](https://www.kimi.com/code)、[源码](https://github.com/MoonshotAI/kimi-code))。本项目在 DeepSeek Harness 的服务之上重新实现这些想法,不包含 Kimi Code 源码,也与 Moonshot AI 无隶属关系。
|
|
160
|
+
- **DeepSeek Harness**:本插件构建所依赖的插件、工具、会话与子代理 API。
|
|
161
|
+
|
|
162
|
+
## License
|
|
163
|
+
|
|
164
|
+
MIT © Loui Finn
|
|
165
|
+
|
|
166
|
+
[](https://github.com/deepseek-ai/deepseek-harness)
|
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
- insert:
|
|
2
|
+
- id: tower
|
|
3
|
+
name: 'dsh-tower'
|
|
4
|
+
config:
|
|
5
|
+
allowAgentControl: true
|
|
6
|
+
- id: preset-tower-worker
|
|
7
|
+
name: '@deepseek-ai/dsh-agent-preset'
|
|
8
|
+
config:
|
|
9
|
+
id: tower-worker
|
|
10
|
+
name: Tower Worker
|
|
11
|
+
description: Executes one Tower mission inside its assigned git worktree.
|
|
12
|
+
order: 60
|
|
13
|
+
plugins:
|
|
14
|
+
- id: tower-worker-policy
|
|
15
|
+
name: 'dsh-tower/worker'
|
|
16
|
+
- id: tower-worker-fs
|
|
17
|
+
name: '@deepseek-ai/dsh-tool-fs'
|
|
18
|
+
- id: tower-worker-fs-search
|
|
19
|
+
name: '@deepseek-ai/dsh-tool-fs-search'
|
|
20
|
+
config:
|
|
21
|
+
sampleOverCapGlobResults: false
|
|
22
|
+
- id: tower-worker-pwsh
|
|
23
|
+
name: '@deepseek-ai/dsh-tool-pwsh'
|
package/icon.svg
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64">
|
|
2
|
+
<rect x="4" y="4" width="56" height="56" rx="12" fill="#141a24"/>
|
|
3
|
+
<rect x="16" y="13" width="32" height="9" rx="2" fill="#f9b98c"/>
|
|
4
|
+
<rect x="20" y="26" width="24" height="8" rx="2" fill="#d98a5f"/>
|
|
5
|
+
<rect x="24" y="38" width="16" height="7" rx="2" fill="#b56f4c"/>
|
|
6
|
+
<path d="M14 52h36" stroke="#8a5238" stroke-width="3" stroke-linecap="round"/>
|
|
7
|
+
</svg>
|