dsh-tower 1.2.0 → 2.0.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/CHANGELOG.md +96 -0
- package/CONTRIBUTING.md +36 -0
- package/README.en.md +60 -23
- package/README.md +54 -21
- package/SECURITY.md +20 -0
- package/cordis.patch.yml +32 -0
- package/docs/README.md +17 -0
- package/docs/architecture/overview.md +70 -0
- package/docs/examples/first-mission.md +58 -0
- package/docs/faq.md +74 -0
- package/docs/guide/hot-reload.md +189 -0
- package/docs/guide/install-upgrade-migration.md +59 -0
- package/docs/guide/quickstart.md +97 -0
- package/docs/operations/runbook.md +80 -0
- package/docs/operations/security.md +62 -0
- package/docs/reference/blockers.md +58 -0
- package/docs/reference/config.md +114 -0
- package/docs/reference/doctor.md +31 -0
- package/docs/reference/errors.md +50 -0
- package/docs/reference/events.md +45 -0
- package/docs/reference/operations.md +52 -0
- package/docs/reference/testing.md +61 -0
- package/docs/reference/tools.md +75 -0
- package/docs/zh/README.md +58 -0
- package/docs/zh/faq.md +72 -0
- package/docs/zh/guide/hot-reload.md +178 -0
- package/docs/zh/guide/install-upgrade-migration.md +57 -0
- package/docs/zh/guide/quickstart.md +96 -0
- package/docs/zh/operations/security.md +42 -0
- package/docs/zh/reference/blockers.md +62 -0
- package/docs/zh/reference/config.md +113 -0
- package/docs/zh/reference/doctor.md +30 -0
- package/docs/zh/reference/errors.md +52 -0
- package/docs/zh/reference/events.md +46 -0
- package/docs/zh/reference/operations.md +48 -0
- package/docs/zh/reference/testing.md +60 -0
- package/docs/zh/reference/tools.md +75 -0
- package/index.js +293 -49
- package/lib/batch.js +578 -0
- package/lib/config.js +381 -0
- package/lib/doctor.js +165 -0
- package/lib/errors.js +111 -0
- package/lib/hmr.js +196 -0
- package/lib/leases.js +317 -0
- package/lib/legacy.js +413 -0
- package/lib/modeStore.js +47 -16
- package/lib/store.js +24 -1
- package/lib/tests.js +628 -0
- package/lib/tools.js +1594 -160
- package/lib/tower.js +1025 -101
- package/lib/workspaceLock.js +117 -0
- package/lib/worktreeOwnership.js +166 -0
- package/package.json +21 -4
- package/reviewer.js +40 -0
- package/scripts/check-docs.mjs +135 -0
- package/scripts/enable-dev-hmr.mjs +347 -0
- package/skills/tower-recovery.md +40 -0
- package/skills/tower-review.md +16 -0
- package/skills/tower-worker-protocol.md +15 -0
- package/skills.js +63 -0
- package/worker.js +7 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,101 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
> 自 2.0.0 起,每个版本按 **新增 / 变更 / 修复** 三类组织;更早的版本保留原始流水式记录。
|
|
4
|
+
|
|
5
|
+
## 2.0.0(2026-10-18)
|
|
6
|
+
|
|
7
|
+
### 新增
|
|
8
|
+
|
|
9
|
+
- **仓库级配置层**:`Tower.open()` 读取 `<git-common-dir>/dsh-tower/config.json`,优先级为
|
|
10
|
+
代码默认 < profile 配置 < 仓库配置 < 工具参数;`review`/`merge`/`worktrees`/`spawn` 分组生效。
|
|
11
|
+
- **稳定工具错误码**:新增 `lib/errors.js`,工具失败统一 `[tower:<code>]` 前缀,覆盖 17 个 code;
|
|
12
|
+
新增 `docs/reference/errors.md` 并由 `npm run docs:check` 校验。
|
|
13
|
+
- **finding 生命周期**:新增 `tower_findings`(列表/读取/状态流转/备注),状态为
|
|
14
|
+
`open → triaged → fixed` / `wontfix` 且可重新打开;只有 tower 或 worker 能改状态,reviewer 只读。
|
|
15
|
+
- **中文文档**:新增 `docs/zh/`(文档索引、quickstart、工具/配置/blocker/错误码参考),
|
|
16
|
+
与英文参考页保持同一套工具名、blocker 与错误码。
|
|
17
|
+
- **测试与门禁**:新增仓库配置、finding 生命周期、工具别名/错误码/输出 schema、spawn mock
|
|
18
|
+
与全流程 schema 校验用例;`docs:check` 同时校验中英文参考页、工具名、blocker 与错误码。
|
|
19
|
+
- **协议硬化**:`tower_interrupt`(停止 running agent)、`tower_send(interrupt:true)`;
|
|
20
|
+
`tower_init` 支持 `autoGitInit`/`snapshotDirty`/`reanchor`;worker 不能直接完成/放弃/扩界,
|
|
21
|
+
completed 必须经 `tower_complete`;单 mission 单活 worker + `takeover` 接管 + generation。
|
|
22
|
+
- **治理与可观测**:可选 `mode.workspaceLock` 仓库互斥;`spawn.maxLiveWorkers`、`send.maxPerMinute`
|
|
23
|
+
与 roster stale 标记;`tower_status` 分页/单 mission 明细/gate digest/markdown;`MISSIONS.md`
|
|
24
|
+
人类可读门板;`tower/*` 进程内事件;`tower_complete.checks` + `gates.requireChecks`。
|
|
25
|
+
- **热重载**:`/tower reload` 与 `tower_reload` 调用 DSH HMR `reconcileProfile`;新增
|
|
26
|
+
`npm run dev:hmr` 脚本把 linked 仓库加入 profile HMR watch root;`docs/guide/hot-reload.md`。
|
|
27
|
+
- **2.1 测试准入**:读取 worktree `package.json` 的 `tower.testDiscovery`(TAP/json-array),支持
|
|
28
|
+
`tests.admission:spawn|complete`、16 MiB/60s 预算、minCount/required;`tower_test` 与
|
|
29
|
+
`tower_complete` 自动生成 `tests` check;`gates.requireTests` / `tests-missing` / `tests-failed`。
|
|
30
|
+
- **2.1 批次与运营**:`tower_batch`(create/status/close,冻结成员、requiredChecks、receiptPaths)、
|
|
31
|
+
`tower_resource`(advisory lease,token/过期显式 force)、`tower_doctor`(只读健康契约)、
|
|
32
|
+
`tower_import_legacy` / `tower_legacy_map`(只读快照 + 审计映射)。
|
|
33
|
+
- **2.1 治理**:per-repo roster watchdog(`spawn.staleMs` 15s 标记 stale 并阻断合并)、
|
|
34
|
+
`spawn.maxWaitMs` 90s、`mode.workspaceLockScope`、plan/tower 互斥(默认清除 plan)、
|
|
35
|
+
`/tower base <branch>`、`docs.boardLocation`、delivery ack、merge intent 持久化。
|
|
36
|
+
- **2.1 UI**:ui-bundle 增加 12 个 tower tool 卡片、composer dock 最新摘要与 shell.overlay 瞬时状态条;
|
|
37
|
+
纯会话派生,无 Host RPC/iframe。
|
|
38
|
+
- **2.1 文档**:`docs/reference/testing.md`、`operations.md`、`doctor.md` 与中文同步;工具面 28。
|
|
39
|
+
|
|
40
|
+
### 变更
|
|
41
|
+
|
|
42
|
+
- **结构化输出 schema**:全部工具声明 output schema(spawn/status/diff/merge/review/preflight
|
|
43
|
+
等核心工具含字段结构),并按 DSH 的输出校验规则保证可空字段可空。
|
|
44
|
+
- **命名统一(兼容别名)**:mission 级工具同时接受 `id` 与 `missionId`;`task_done`/`taskDone`、
|
|
45
|
+
`task_drop`/`taskDrop`、`clear_blockers`/`clearBlockers`、`include_read`/`includeRead`、
|
|
46
|
+
`dry_run`/`dryRun`、`timeoutMs`/`timeout_ms`、`waitMs`/`wait_ms` 等写法均可,并在参数 schema
|
|
47
|
+
中显式声明;输出保持既有规范。
|
|
48
|
+
- **诊断信息**:`tower_status` 增加 `config.path`、`config.repoConfigPresent` 与
|
|
49
|
+
`findingsByStatus`;worker/reviewer preset 允许 `tower_findings`。
|
|
50
|
+
- **配置解析**:兼容别名只用于补缺——同时设置 `section` 与 `mode.promptSection` 时规范键优先;
|
|
51
|
+
仓库配置增加 1 MiB 大小上限与 `__proto__`/`constructor`/`prototype` 等危险键拒绝。
|
|
52
|
+
- **配置默认值**:`mode.denyTools` 追加 workflow/ralph/subagent/subagent_fork/wait_agent/team_task_list
|
|
53
|
+
(Tower 模式与其它编排互斥);新增 `spawn.maxLiveWorkers:4`、`spawn.staleMs:15000`、
|
|
54
|
+
`spawn.maxWaitMs:90000`、`send.maxPerMinute:120`、`gates.requireChecks:false`、
|
|
55
|
+
`gates.requireTests:false`、`docs.board:true`、`leases.ttlMs:900000`、`dev.hotReload:true`;
|
|
56
|
+
随包 patch 打开 `workspaceLock`/`interruptDefault`/`autoGitInit`。
|
|
57
|
+
- **briefing**:worker/reviewer 生成历史审查、上一轮 findings/decision、completion checks 与
|
|
58
|
+
related findings,长文本截断;reviewer 必须核对 completion checks。
|
|
59
|
+
- **输出/工具面**:`tower_status` 增加 total/offset/nextOffset/detail/markdown,并**默认只返回前 20 个 mission**(旧版返回全部;旧调用需要更多时用 `limit`/`offset`);`tower_adopt`
|
|
60
|
+
支持 `retireMissing:false`;`tower_mode` 返回 pluginVersion/HMR/workspace lock;`tower_roster`
|
|
61
|
+
增加 `stale`。工具总数最多 28(含 doctor/test/batch/resource/import/legacy_map 与可选的 control/reload)。
|
|
62
|
+
- **离线套件**:测试增至 206 项(含 2.1 discovery/batch/leases/legacy/doctor/UI/plan-mode/integration 用例)。
|
|
63
|
+
- 除 `tower_status` 默认分页与 `mode.denyTools` 默认扩充外,既有工具参数与输出保持兼容。
|
|
64
|
+
|
|
65
|
+
### 修复
|
|
66
|
+
|
|
67
|
+
- **模式工具 schema 与返回值不一致**:`tower_mode`/`tower_control` 的 `lastChange`、`pausedGoal`、
|
|
68
|
+
`goalNote` 在正常路径返回 `null`,原 schema 会触发 DSH 强制输出校验失败;已改为可空并补回归测试。
|
|
69
|
+
- **错误码分类补全**:state 校验失败统一归为 `state-corrupt`;`tower_complete` 的未完成任务、
|
|
70
|
+
blocker、无提交、未读消息等前置条件归为 `invalid-transition`,不再落到 `tool-internal`。
|
|
71
|
+
- **findings 更新后的计数**:状态流转后返回的 `counts` 之前是旧值,现在按变更后重新统计。
|
|
72
|
+
- **findings 只读路径**:列表/读取不再获取写锁,与工具描述一致,长合并或 hook 期间也能读取。
|
|
73
|
+
- **mission id 规范化**:`tower_mission` 对首尾空白的 `id` 先 trim 再查找,不再误报
|
|
74
|
+
`mission-not-found`。
|
|
75
|
+
- **角色绕过**:worker 之前可经 `tower_mission` 直接 completed/abandoned/扩界或清 blocker,
|
|
76
|
+
绕过 `tower_complete` 的未读/提交证据;现由服务端角色强制。
|
|
77
|
+
- **并发与接管**:同一 mission 不再允许出现第二个 live worker;stale/interrupted/failed 的
|
|
78
|
+
worker 可显式 takeover,running worker 必须先中断,否则 `takeover-refused`。
|
|
79
|
+
|
|
80
|
+
## 1.3.0 — 2026-10-18
|
|
81
|
+
|
|
82
|
+
- **独立的只读 reviewer preset**:新增 `reviewer.js` / `tower-reviewer`,去掉 `write`/`edit`/`pwsh`/
|
|
83
|
+
`tower_mission`/`tower_complete`,只保留读、`tower_diff`、消息、finding、review;`tower_spawn`
|
|
84
|
+
按 role 映射 preset,reviewer 必须等待 mission `completed`。`tower_review` 会记录 reviewer spawn
|
|
85
|
+
时的 tip,审查期间改动分支将被拒绝(修复自审风险)。
|
|
86
|
+
- **新增 `tower_diff`**:只读 merge-base diff(files/commits/patch),供 reviewer 使用。
|
|
87
|
+
- **声明 `Config` schema**:`section`/`allowAgentControl` 兼容别名 + `mode`/`review`/`merge`/
|
|
88
|
+
`worktrees`/`spawn` 分组;评审轮数、合并超时/缓冲、worktree 根、spawn preset/model 等可配置;
|
|
89
|
+
`mode.storePath`/`maxEntries`/`autoPauseGoal`/`denyTools`/`sectionAppend` 生效。
|
|
90
|
+
- **spawn 健壮性**:preset 存在性预检、按 role 选择 preset/model、失败/空闲状态写回 roster。
|
|
91
|
+
- **内置 Agent Skills**:`skills/tower-worker-protocol`、`skills/tower-review`、`skills/tower-recovery`,
|
|
92
|
+
通过 `dsh-tower/skills` provider 注册;worker/reviewer preset 允许 `skill`。
|
|
93
|
+
- **文档**:新增 `docs/`(quickstart、安装升级迁移、工具/配置/blocker 参考、架构、运维、安全、FAQ、
|
|
94
|
+
示例);README quick start 修正为“先 reviewer 后 preflight 全绿”,工具数/测试数/blocker 数修正;
|
|
95
|
+
`npm run docs:check` 与 CI 校验文档与代码一致。
|
|
96
|
+
- `package.json` 增加 `@deepseek-ai/schemastery` 依赖、`files` 补充 reviewer/skills/docs/贡献与安全文档。
|
|
97
|
+
- 测试 26 项(新增 preset/skills/config 四个用例)。
|
|
98
|
+
|
|
3
99
|
## 1.2.0 — 2026-10-18
|
|
4
100
|
|
|
5
101
|
- **`tower_merge` 对“提交已落地但调用报错”的恢复**:合并命令失败/超时后检查 `HEAD`,若已是
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in `dsh-tower`. This is a DeepSeek Harness plugin; the repository root is the bundle itself (`package.json` + `cordis.patch.yml`).
|
|
4
|
+
|
|
5
|
+
## Development setup
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
git clone https://github.com/louifinn/dsh-tower.git
|
|
9
|
+
cd dsh-tower
|
|
10
|
+
npm test # no dependencies to install; Node's built-in test runner only
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Requirements: Node.js 22+, Git. No package installation is needed for the offline suite.
|
|
14
|
+
|
|
15
|
+
## What to change
|
|
16
|
+
|
|
17
|
+
- `index.js` — Host entry: `/tower` command, mode guard, dynamic prompt section, `tower_control`.
|
|
18
|
+
- `lib/` — the Tower domain (`tower.js`), tool definitions (`tools.js`), persistence (`store.js`, `modeStore.js`), Git helpers (`git.js`).
|
|
19
|
+
- `worker.js` — the `tower-worker` preset policy (tool surface + protocol text).
|
|
20
|
+
- `tests/` — add a regression test for every behavior change. The offline suite is `tests/*.test.mjs`; live-runtime scripts are documented in `tests/README.md`.
|
|
21
|
+
|
|
22
|
+
## Pull request checklist
|
|
23
|
+
|
|
24
|
+
1. `npm test` passes locally (206 tests today, including protocol end-to-end against a real temporary Git repository and mock spawn coverage) and `npm run docs:check` passes.
|
|
25
|
+
2. New behavior has a test. Bug fixes should add a test that fails before the fix.
|
|
26
|
+
3. No secrets, tokens, personal paths, session logs, or generated artifacts are added. `.gitignore` covers local acceptance output; do not force-add it.
|
|
27
|
+
4. Keep the public API and state-file formats compatible; if a change is breaking, call it out in `CHANGELOG.md` and bump the version.
|
|
28
|
+
5. Update `README.md` / `README.en.md` when the user-visible behavior changes.
|
|
29
|
+
|
|
30
|
+
## Commit style
|
|
31
|
+
|
|
32
|
+
Conventional-commit prefixes are preferred: `feat:`, `fix:`, `docs:`, `test:`, `refactor:`, `chore:`. Keep the subject line in the imperative mood.
|
|
33
|
+
|
|
34
|
+
## Reporting issues
|
|
35
|
+
|
|
36
|
+
Include the DSH version, Node.js version, the exact `/tower` or tool input, and the relevant error text. Redact paths, tokens, session ids, and any personal data from logs before posting. For security issues, see [SECURITY.md](SECURITY.md).
|
package/README.en.md
CHANGED
|
@@ -18,6 +18,14 @@ The repository root **is** the DSH bundle: `package.json` declares `dsh.bundle.p
|
|
|
18
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
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
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
|
+
- **Traceable finding lifecycle.** `tower_findings` lists, reads, and moves findings through `open → triaged → fixed` / `wontfix` (and can reopen); only the tower or a worker may change state, while reviewers can only read.
|
|
22
|
+
- **Repository-level config.** Any repository can override review/merge/worktree/spawn policy in `<git-common-dir>/dsh-tower/config.json`; tool arguments override the repository layer, so no profile edit is needed per repository.
|
|
23
|
+
- **Stable error codes.** Tool failures carry a `[tower:<code>]` prefix (for example `mission-not-found`, `preset-missing`, `config-invalid`) so callers can branch deterministically.
|
|
24
|
+
- **Role enforcement and control.** Workers cannot complete/abandon a mission or widen its scope directly (completion goes through the `tower_complete` evidence gate); the tower can stop a runaway agent with `tower_interrupt`, and `tower_send(interrupt:true)` interrupts a running turn.
|
|
25
|
+
- **Workspace exclusivity and limits.** Optional `mode.workspaceLock` allows one Tower session per repository; `spawn.maxLiveWorkers`, `send.maxPerMinute` and roster stale flags bound concurrency and message bursts.
|
|
26
|
+
- **2.1 verification and operations.** `tower_test` runs the worktree's `tower.testDiscovery` (TAP/json-array, admission at spawn or complete), `tower_doctor` is a read-only health contract, `tower_batch` closes finite evidence batches, `tower_resource` manages advisory leases, and `tower_import_legacy`/`tower_legacy_map` import old snapshots and audit-map ids. Adds `worker-stale`, test gates, plan/Tower mutual exclusion, `workspaceLockScope`, `docs.boardLocation` and delivery acknowledgements.
|
|
27
|
+
- **Hot reload.** In a profile with DSH HMR, `/tower reload`, `tower_reload` and `npm run dev:hmr` apply linked plugin changes without a restart; `plugin_manager` install/update already applies live.
|
|
28
|
+
- **Evidence gate and events.** Workers can record `checks` in `tower_complete` and `gates.requireChecks` can require them; every mutation emits `tower/*` events and refreshes `MISSIONS.md`.
|
|
21
29
|
|
|
22
30
|
## Requirements
|
|
23
31
|
|
|
@@ -50,24 +58,23 @@ The Host plugin is loaded when the DSH process starts, so **restart DSH after in
|
|
|
50
58
|
|
|
51
59
|
## Quick start
|
|
52
60
|
|
|
53
|
-
```
|
|
61
|
+
```text
|
|
54
62
|
/tower on
|
|
55
63
|
|
|
56
|
-
tower_init
|
|
57
|
-
tower_plan
|
|
58
|
-
tower_spawn
|
|
59
|
-
# worker implements and
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
tower_teardown <repoRoot>
|
|
64
|
+
tower_init repoRoot=D:\work\repo # records the base (current branch by default)
|
|
65
|
+
tower_plan repoRoot=D:\work\repo missions=[{"title":"Feature A","scope":["src/a/**"],"tasks":["implement","commit"],"kind":"build"}]
|
|
66
|
+
tower_spawn repoRoot=D:\work\repo missionId=M1 role=worker
|
|
67
|
+
# the worker implements and commits in its worktree, calls tower_complete; its final report returns here
|
|
68
|
+
tower_spawn repoRoot=D:\work\repo missionId=M1 role=reviewer
|
|
69
|
+
# the reviewer inspects read-only and calls tower_review (clean+merge, or p1-Nitems/p2-Nitems)
|
|
70
|
+
tower_preflight repoRoot=D:\work\repo missionId=M1 # expect no-review before review; ok:true after it
|
|
71
|
+
tower_merge repoRoot=D:\work\repo missionId=M1
|
|
72
|
+
tower_teardown repoRoot=D:\work\repo
|
|
66
73
|
|
|
67
74
|
/tower off
|
|
68
75
|
```
|
|
69
76
|
|
|
70
|
-
A
|
|
77
|
+
A small change usually takes one worker mission and one reviewer round. A full copy-paste example is in [docs/examples/first-mission.md](docs/examples/first-mission.md); per-tool parameters are in [docs/reference/tools.md](docs/reference/tools.md).
|
|
71
78
|
|
|
72
79
|
## Commands
|
|
73
80
|
|
|
@@ -88,28 +95,44 @@ Image and file attachments are forwarded together with the instruction as one co
|
|
|
88
95
|
- id: tower
|
|
89
96
|
name: 'dsh-tower'
|
|
90
97
|
config:
|
|
91
|
-
section: 'Optional
|
|
92
|
-
allowAgentControl: true #
|
|
98
|
+
section: 'Optional legacy alias replacing the Tower-mode prompt text'
|
|
99
|
+
allowAgentControl: true # legacy alias for mode.allowAgentControl
|
|
100
|
+
mode:
|
|
101
|
+
allowAgentControl: true
|
|
102
|
+
autoPauseGoal: true
|
|
103
|
+
denyTools: [create_goal, todo_write, team_task_create, team_task_update, team_task_reopen, spawn_teammate]
|
|
104
|
+
review:
|
|
105
|
+
maxRoundsPerReviewer: 5
|
|
106
|
+
merge:
|
|
107
|
+
timeoutMs: 900000
|
|
108
|
+
worktrees:
|
|
109
|
+
root: '' # empty = <checkout parent>/.dsh-tower-worktrees/<hash>
|
|
110
|
+
spawn:
|
|
111
|
+
workerPreset: tower-worker
|
|
112
|
+
reviewerPreset: tower-reviewer
|
|
113
|
+
maxDepth: 1
|
|
93
114
|
```
|
|
94
115
|
|
|
95
|
-
- `allowAgentControl` defaults to `false` in code
|
|
96
|
-
-
|
|
116
|
+
- `mode.allowAgentControl` defaults to `false` in code; the bundled `cordis.patch.yml` enables it (`true`) so the model may enter/leave when the user intent or task state warrants it, always stating a reason. The bundled patch also enables `mode.workspaceLock` (single-active tower), `send.interruptDefault`, `init.autoGitInit`, and sets `spawn.staleMs` to 15s.
|
|
117
|
+
- `/tower base <branch>` records a session-level init base preference; `/tower on` clears an active plan mode (`mode.planModePolicy:"refuse"` instead refuses entry), keeping plan and Tower mutually exclusive.
|
|
118
|
+
- Repository-level config: put the same JSON shape in `<git-common-dir>/dsh-tower/config.json` (usually `.git/dsh-tower/config.json`) to override `review`/`merge`/`worktrees`/`spawn`. Precedence is code defaults < profile config < repository config < tool arguments. `mode.*` is session-scoped and only the profile layer controls it.
|
|
119
|
+
- Every key and default is in [docs/reference/config.md](docs/reference/config.md); unknown top-level keys are rejected so typos cannot silently disable security-relevant settings, while unknown keys inside a group are ignored. Tool error codes are in [docs/reference/errors.md](docs/reference/errors.md).
|
|
97
120
|
|
|
98
|
-
## Tools (
|
|
121
|
+
## Tools (26 core)
|
|
99
122
|
|
|
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`
|
|
123
|
+
`tower_init` · `tower_plan` · `tower_mission` · `tower_status` · `tower_spawn` · `tower_roster` · `tower_adopt` · `tower_diff` · `tower_send` · `tower_inbox` · `tower_complete` · `tower_interrupt` · `tower_finding` · `tower_findings` · `tower_review` · `tower_preflight` · `tower_merge` · `tower_rebase` · `tower_teardown` · `tower_mode` · `tower_doctor` · `tower_test` · `tower_batch` · `tower_resource` · `tower_import_legacy` · `tower_legacy_map`
|
|
101
124
|
|
|
102
|
-
`tower_control` exists only when `allowAgentControl: true
|
|
125
|
+
`tower_control` exists only when `allowAgentControl: true`; `tower_reload` is registered while `dev.hotReload` is on (default true) and returns `reload-unavailable` without an HMR service (so up to 28 tools). Mission-scoped tools also accept `id` as an alias for `missionId`; snake/camel spellings such as `task_done`/`taskDone` are both accepted.
|
|
103
126
|
|
|
104
127
|
## Safety and guardrails
|
|
105
128
|
|
|
106
129
|
- **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.**
|
|
130
|
+
- **Review is bound to a commit.** A moved tip reports `tip-moved` and requires a fresh review; reviewers use a read-only preset, and a branch change during review is rejected.
|
|
108
131
|
- **Scope enforcement.** A mission may only change files matched by its declared scope globs; `out-of-scope` blocks the merge.
|
|
109
132
|
- **Worktree ownership.** Dirty worktrees, a running worker, or a branch owned by a closed mission block teardown/merge.
|
|
110
133
|
- **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
134
|
|
|
112
|
-
|
|
135
|
+
32 stable blocker/failure codes (including gate guards, `no-check-evidence`, `worker-stale`, test gates, and merge/rebase operation failures) — the complete list with triggers and fixes is in [docs/reference/blockers.md](docs/reference/blockers.md). Tool-level error codes are in [docs/reference/errors.md](docs/reference/errors.md); events are in [docs/reference/events.md](docs/reference/events.md).
|
|
113
136
|
|
|
114
137
|
## How it works
|
|
115
138
|
|
|
@@ -122,14 +145,16 @@ A mission moves through `planned → active → completed → merged` (or `block
|
|
|
122
145
|
| `<checkout parent>/.dsh-tower-worktrees/<hash>/<missionId>` | per-mission worktree |
|
|
123
146
|
| `$DSH_HOME/tower-mode/modes.json` | Tower mode state per agent/session |
|
|
124
147
|
|
|
125
|
-
Workers
|
|
148
|
+
Workers use the bundled `tower-worker` preset (writable worktree surface); reviewers use the separate read-only `tower-reviewer` preset and can only inspect (`tower_diff`) and submit `tower_review`. The reviewer records the branch tip at spawn; if the branch moves, the review is rejected. Neither preset can merge or spawn.
|
|
126
149
|
|
|
127
150
|
## Project layout
|
|
128
151
|
|
|
129
152
|
| Path | Contents |
|
|
130
153
|
|---|---|
|
|
131
154
|
| `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
|
|
155
|
+
| `index.js`, `lib/`, `worker.js`, `reviewer.js` | Host entry, protocol/config implementation, worker and reviewer preset policies |
|
|
156
|
+
| `skills.js`, `skills/` | bundled agent skills (worker protocol, review checklist, recovery playbook) |
|
|
157
|
+
| `docs/` | guides, reference, architecture, operations, FAQ and examples |
|
|
133
158
|
| `locale/`, `icon.svg` | localization and icon |
|
|
134
159
|
| `tests/` | pure-function, protocol end-to-end, and plugin-level tests; optional isolated Web-runtime scripts |
|
|
135
160
|
| `ui-bundle/` | optional Client widget (static `/tower` hint), not installed by default |
|
|
@@ -141,8 +166,20 @@ Workers and reviewers are ordinary DSH subagents started with the bundled `tower
|
|
|
141
166
|
npm test # node --test tests/*.test.mjs
|
|
142
167
|
```
|
|
143
168
|
|
|
169
|
+
Hot-reload development: `npm run dev:hmr` adds this checkout to the current profile's HMR watch roots
|
|
170
|
+
(one DSH restart); afterwards `/tower reload` or the automatic watcher applies `lib/` edits. See
|
|
171
|
+
[docs/guide/hot-reload.md](docs/guide/hot-reload.md).
|
|
172
|
+
|
|
144
173
|
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
174
|
|
|
175
|
+
## Documentation
|
|
176
|
+
|
|
177
|
+
- [docs/README.md](docs/README.md) — documentation index (new user / operator / maintainer paths)
|
|
178
|
+
- [Chinese docs](docs/zh/README.md) · [Quick start](docs/guide/quickstart.md) · [Install, upgrade and migration](docs/guide/install-upgrade-migration.md)
|
|
179
|
+
- [Tools reference](docs/reference/tools.md) · [Config reference](docs/reference/config.md) · [Blockers and failure codes](docs/reference/blockers.md) · [Error codes](docs/reference/errors.md) · [Events](docs/reference/events.md) · [Testing](docs/reference/testing.md) · [Batches/leases/legacy](docs/reference/operations.md) · [Doctor](docs/reference/doctor.md) · [Hot reload](docs/guide/hot-reload.md)
|
|
180
|
+
- [Architecture and state machine](docs/architecture/overview.md) · [Operations runbook](docs/operations/runbook.md) · [Security model](docs/operations/security.md)
|
|
181
|
+
- [FAQ](docs/faq.md) · [Examples](docs/examples/first-mission.md)
|
|
182
|
+
|
|
146
183
|
## Troubleshooting
|
|
147
184
|
|
|
148
185
|
- **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.
|
package/README.md
CHANGED
|
@@ -18,6 +18,14 @@ Tower 模式与 mission/审查工作流的灵感来自 Moonshot AI 的 **Kimi Co
|
|
|
18
18
|
- **审查门禁合并。** 审查者必须针对当前分支 tip 给出 `clean` / `merge` 结论;合并门禁重新校验 scope、分支新鲜度、任务完成度、审查记录与 worktree 归属,通过后才执行 `--no-ff` 合并。
|
|
19
19
|
- **可恢复的协作状态。** roster、inbox、findings、reviews 与 mission 状态持久化在 `.git/dsh-tower/` 下,重启不会丢计划。
|
|
20
20
|
- **默认安全。** Tower 模式开启期间拒绝 `create_goal`、`update_goal(resume)`、`todo_write`、Team 任务板与 `spawn_teammate`;被暂停的 goal 不会被自动恢复。
|
|
21
|
+
- **可追溯的 finding 生命周期。** `tower_findings` 列表、读取并按 `open → triaged → fixed` / `wontfix` 流转,也可重新打开;只有 tower 或 worker 能改状态,reviewer 只能读。
|
|
22
|
+
- **仓库级配置。** 每个仓库可用 `<git-common-dir>/dsh-tower/config.json` 覆盖 review/merge/worktree/spawn 策略,工具参数再覆盖仓库配置;无需为不同仓库改 profile。
|
|
23
|
+
- **稳定错误码。** 工具失败统一带 `[tower:<code>]` 前缀(如 `mission-not-found`、`preset-missing`、`config-invalid`),调用方可稳定分支处理。
|
|
24
|
+
- **角色强制与可控中断。** worker 不能直接完成/放弃 mission 或扩界(完成必须走 `tower_complete` 证据门),tower 可随时用 `tower_interrupt` 停止跑偏的 agent;`tower_send(interrupt:true)` 可中止运行中的 turn。
|
|
25
|
+
- **仓库互斥与限流。** 可选 `mode.workspaceLock` 让同一仓库只有一个 Tower 会话;`spawn.maxLiveWorkers`、`send.maxPerMinute`、roster stale 标记约束并发与消息风暴。
|
|
26
|
+
- **可热重载。** 在带 DSH HMR 的 profile 中,`/tower reload`、`tower_reload` 与 `npm run dev:hmr` 让 linked 插件代码改动无需重启即生效;`plugin_manager` 安装/更新本身即时生效。
|
|
27
|
+
- **测试证据门与事件。** worker 可在 `tower_complete` 记录 `checks`,`gates.requireChecks` 可强制;每次 mutation 后发射 `tower/*` 事件并刷新 `MISSIONS.md`。
|
|
28
|
+
- **2.1 验证与运营。** `tower_test` 执行 worktree 声明的 `tower.testDiscovery`(TAP/json-array,准入可设 spawn/complete),`tower_doctor` 只读健康契约,`tower_batch` 批次证据收口,`tower_resource` advisory lease,`tower_import_legacy` / `tower_legacy_map` 只读旧版导入与审计映射;新增 `worker-stale`、tests 门禁、plan/tower 互斥、`workspaceLockScope`、`docs.boardLocation` 与交付 ack。
|
|
21
29
|
|
|
22
30
|
## 环境要求
|
|
23
31
|
|
|
@@ -50,24 +58,23 @@ Host 插件在 DSH 进程启动时加载,**安装或更新后需重启 DSH**
|
|
|
50
58
|
|
|
51
59
|
## 快速开始
|
|
52
60
|
|
|
53
|
-
```
|
|
61
|
+
```text
|
|
54
62
|
/tower on
|
|
55
63
|
|
|
56
|
-
tower_init
|
|
57
|
-
tower_plan
|
|
58
|
-
tower_spawn
|
|
59
|
-
# worker
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
tower_teardown <repoRoot>
|
|
64
|
+
tower_init repoRoot=D:\work\repo # 首次初始化,记录 base(默认当前分支)
|
|
65
|
+
tower_plan repoRoot=D:\work\repo missions=[{"title":"Feature A","scope":["src/a/**"],"tasks":["implement","commit"],"kind":"build"}]
|
|
66
|
+
tower_spawn repoRoot=D:\work\repo missionId=M1 role=worker
|
|
67
|
+
# worker 在 worktree 内实现并提交,调用 tower_complete;最终报告会返回本会话
|
|
68
|
+
tower_spawn repoRoot=D:\work\repo missionId=M1 role=reviewer
|
|
69
|
+
# reviewer 只读审查并调用 tower_review(clean+merge 或 p1-Nitems/p2-Nitems)
|
|
70
|
+
tower_preflight repoRoot=D:\work\repo missionId=M1 # 审查前 预期 no-review;审查后应为 ok:true
|
|
71
|
+
tower_merge repoRoot=D:\work\repo missionId=M1
|
|
72
|
+
tower_teardown repoRoot=D:\work\repo
|
|
66
73
|
|
|
67
74
|
/tower off
|
|
68
75
|
```
|
|
69
76
|
|
|
70
|
-
小改动通常一轮 worker + 一轮 reviewer
|
|
77
|
+
小改动通常一轮 worker + 一轮 reviewer 即可完成。完整可复制示例见 [docs/examples/first-mission.md](docs/examples/first-mission.md),逐工具参数见 [docs/reference/tools.md](docs/reference/tools.md)。
|
|
71
78
|
|
|
72
79
|
## 命令
|
|
73
80
|
|
|
@@ -88,28 +95,44 @@ tower_teardown <repoRoot>
|
|
|
88
95
|
- id: tower
|
|
89
96
|
name: 'dsh-tower'
|
|
90
97
|
config:
|
|
91
|
-
section: '
|
|
92
|
-
allowAgentControl: true #
|
|
98
|
+
section: '(可选,兼容别名)覆盖 Tower 模式系统提示文案'
|
|
99
|
+
allowAgentControl: true # 兼容别名;等价于 mode.allowAgentControl
|
|
100
|
+
mode:
|
|
101
|
+
allowAgentControl: true
|
|
102
|
+
autoPauseGoal: true
|
|
103
|
+
denyTools: [create_goal, todo_write, team_task_create, team_task_update, team_task_reopen, spawn_teammate]
|
|
104
|
+
review:
|
|
105
|
+
maxRoundsPerReviewer: 5
|
|
106
|
+
merge:
|
|
107
|
+
timeoutMs: 900000
|
|
108
|
+
worktrees:
|
|
109
|
+
root: '' # 空 = <主检出父目录>/.dsh-tower-worktrees/<hash>
|
|
110
|
+
spawn:
|
|
111
|
+
workerPreset: tower-worker
|
|
112
|
+
reviewerPreset: tower-reviewer
|
|
113
|
+
maxDepth: 1
|
|
93
114
|
```
|
|
94
115
|
|
|
95
|
-
- 代码中 `allowAgentControl` 默认 `false
|
|
96
|
-
-
|
|
116
|
+
- 代码中 `mode.allowAgentControl` 默认 `false`;随包 `cordis.patch.yml` 设为 `true`:模型可在用户意图/任务状态明确时自行进出,但必须给出理由;设为 `false` 时只有人类能切换。随包 patch 还默认开启 `mode.workspaceLock`(单活塔)、`send.interruptDefault`、`init.autoGitInit`,并把 `spawn.staleMs` 设为 15s。
|
|
117
|
+
- `/tower base <branch>` 可设置会话级 init base 偏好;`/tower on` 会清除活跃 plan mode(`mode.planModePolicy:"refuse"` 则拒绝进入),保证 plan/tower 互斥。
|
|
118
|
+
- 仓库级配置:在 `<git-common-dir>/dsh-tower/config.json`(通常是 `.git/dsh-tower/config.json`)放入同样的 JSON 结构,可覆盖 `review`/`merge`/`worktrees`/`spawn`;优先级为代码默认 < profile < 仓库配置 < 工具参数。`mode.*` 属于会话级,只在 profile 生效。
|
|
119
|
+
- 所有键与默认值见 [docs/reference/config.md](docs/reference/config.md);未知顶层键会被拒绝(防止拼写错误静默失效),嵌套分组内的未知键会被忽略。工具错误码见 [docs/reference/errors.md](docs/reference/errors.md)。
|
|
97
120
|
|
|
98
|
-
## 工具(
|
|
121
|
+
## 工具(26 个核心)
|
|
99
122
|
|
|
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`
|
|
123
|
+
`tower_init` · `tower_plan` · `tower_mission` · `tower_status` · `tower_spawn` · `tower_roster` · `tower_adopt` · `tower_diff` · `tower_send` · `tower_inbox` · `tower_complete` · `tower_interrupt` · `tower_finding` · `tower_findings` · `tower_review` · `tower_preflight` · `tower_merge` · `tower_rebase` · `tower_teardown` · `tower_mode` · `tower_doctor` · `tower_test` · `tower_batch` · `tower_resource` · `tower_import_legacy` · `tower_legacy_map`
|
|
101
124
|
|
|
102
|
-
`tower_control` 仅在 `allowAgentControl: true`
|
|
125
|
+
`tower_control` 仅在 `allowAgentControl: true` 时注册;`tower_reload` 在 `dev.hotReload`(默认 true)时注册,无 HMR 服务调用会返回 `reload-unavailable`(因此最多 28 个工具)。mission 级工具同时接受 `id` 作为 `missionId` 的别名;`task_done`/`taskDone` 等 snake/camel 写法均可。
|
|
103
126
|
|
|
104
127
|
## 安全与约束
|
|
105
128
|
|
|
106
129
|
- **门禁不全绿不合并。** `tower_preflight` 是只读检查,返回稳定的 blocker code;存在 blocker 时 `tower_merge` 拒绝合并。
|
|
107
|
-
- **审查绑定提交。** 审查后分支 tip 变化会报 `tip-moved
|
|
130
|
+
- **审查绑定提交。** 审查后分支 tip 变化会报 `tip-moved`,必须重新审查;reviewer 使用只读 preset,若在审查期间改动分支,提交审查会被拒绝。
|
|
108
131
|
- **scope 强制。** mission 只能修改其 scope glob 匹配的文件,越界会以 `out-of-scope` 阻止合并。
|
|
109
132
|
- **worktree 归属。** 脏工作树、运行中的 worker、已关闭 mission 的分支都会阻止合并或 teardown。
|
|
110
133
|
- **goal 隔离。** 进入 Tower 模式会暂停活跃 goal 并记录;退出不会自动恢复,需要你自行恢复。
|
|
111
134
|
|
|
112
|
-
|
|
135
|
+
32 个稳定 blocker/failure code(含 gate 守卫、`no-check-evidence`、worker-stale、tests 门禁与 merge/rebase 操作失败码)——完整清单、触发条件与修复动作见 [docs/reference/blockers.md](docs/reference/blockers.md)。工具本身抛出的错误码见 [docs/reference/errors.md](docs/reference/errors.md),事件见 [docs/reference/events.md](docs/reference/events.md)。
|
|
113
136
|
|
|
114
137
|
## 工作原理
|
|
115
138
|
|
|
@@ -141,8 +164,18 @@ worker 与 reviewer 是使用内置 `tower-worker` preset 的普通 DSH 子代
|
|
|
141
164
|
npm test # node --test tests/*.test.mjs
|
|
142
165
|
```
|
|
143
166
|
|
|
167
|
+
热重载开发:`npm run dev:hmr` 把本仓库加入当前 profile 的 HMR watch root(需重启 DSH 一次),之后编辑 `lib/` 代码可用 `/tower reload` 或自动 watch 生效;详见 [docs/guide/hot-reload.md](docs/guide/hot-reload.md)。
|
|
168
|
+
|
|
144
169
|
离线套件不需要 DSH 进程,只在系统临时目录创建一次性 Git 仓库。隔离 Web 运行时检查、模型驱动验收和会话诊断脚本见 `tests/README.md`。
|
|
145
170
|
|
|
171
|
+
## 文档
|
|
172
|
+
|
|
173
|
+
- [docs/README.md](docs/README.md) — 文档索引(新用户 / 运维 / 维护者三条阅读路径)
|
|
174
|
+
- [中文文档](docs/zh/README.md) · [快速开始](docs/guide/quickstart.md) · [安装、升级与迁移](docs/guide/install-upgrade-migration.md)
|
|
175
|
+
- [工具参考](docs/reference/tools.md) · [配置参考](docs/reference/config.md) · [blocker 与失败码](docs/reference/blockers.md) · [错误码](docs/reference/errors.md) · [事件](docs/reference/events.md) · [测试准入](docs/reference/testing.md) · [批次/租约/旧版](docs/reference/operations.md) · [Doctor](docs/reference/doctor.md) · [热重载](docs/guide/hot-reload.md)
|
|
176
|
+
- [架构与状态机](docs/architecture/overview.md) · [运维 runbook](docs/operations/runbook.md) · [安全模型](docs/operations/security.md)
|
|
177
|
+
- [FAQ](docs/faq.md) · [示例](docs/examples/first-mission.md)
|
|
178
|
+
|
|
146
179
|
## 常见问题
|
|
147
180
|
|
|
148
181
|
- **安装/更新后插件不出现。** Host 插件在 DSH 启动时加载,请重启 DSH;并确认安装目标指向本仓库根目录(含 `package.json` 与 `cordis.patch.yml` 的那一层),而不是子目录。
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Security policy
|
|
2
|
+
|
|
3
|
+
## Scope
|
|
4
|
+
|
|
5
|
+
`dsh-tower` runs inside a local DeepSeek Harness process. It does not send data to any network service of its own: mission state is written under the target repository's `.git/dsh-tower/`, and Tower-mode state is written under `$DSH_HOME/tower-mode/`.
|
|
6
|
+
|
|
7
|
+
Areas that matter for security reports:
|
|
8
|
+
|
|
9
|
+
- The merge gate (`tower_preflight` / `tower_merge`): bypassing scope, review, staleness, or ownership checks.
|
|
10
|
+
- The mode guard: reaching a denied tool (`create_goal`, `todo_write`, Team task tools, `spawn_teammate`, `update_goal(resume)`) while Tower mode is active.
|
|
11
|
+
- Command forwarding: injecting content into the model history that the user did not send.
|
|
12
|
+
- Writes outside the declared scope, the mission worktree, or the DSH home directory.
|
|
13
|
+
|
|
14
|
+
## Reporting
|
|
15
|
+
|
|
16
|
+
Please do **not** publish exploit details in a public issue. Open a minimal issue titled `security: request private contact` describing only the impact category (for example “merge gate bypass”), and a maintainer will arrange a private channel. Include the affected version and, if possible, a minimal reproduction in the private follow-up.
|
|
17
|
+
|
|
18
|
+
## Supported versions
|
|
19
|
+
|
|
20
|
+
Security fixes target the latest released version (`1.x`). Older pre-release snapshots are not maintained.
|
package/cordis.patch.yml
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
3
3
|
name: 'dsh-tower'
|
|
4
4
|
config:
|
|
5
5
|
allowAgentControl: true
|
|
6
|
+
init:
|
|
7
|
+
autoGitInit: true
|
|
8
|
+
mode:
|
|
9
|
+
workspaceLock: true
|
|
10
|
+
workspaceLockScope: all
|
|
11
|
+
planModePolicy: clear
|
|
12
|
+
send:
|
|
13
|
+
interruptDefault: true
|
|
14
|
+
spawn:
|
|
15
|
+
staleMs: 15000
|
|
16
|
+
- id: tower-skills
|
|
17
|
+
name: 'dsh-tower/skills'
|
|
6
18
|
- id: preset-tower-worker
|
|
7
19
|
name: '@deepseek-ai/dsh-agent-preset'
|
|
8
20
|
config:
|
|
@@ -21,3 +33,23 @@
|
|
|
21
33
|
sampleOverCapGlobResults: false
|
|
22
34
|
- id: tower-worker-pwsh
|
|
23
35
|
name: '@deepseek-ai/dsh-tool-pwsh'
|
|
36
|
+
- id: preset-tower-reviewer
|
|
37
|
+
name: '@deepseek-ai/dsh-agent-preset'
|
|
38
|
+
config:
|
|
39
|
+
id: tower-reviewer
|
|
40
|
+
name: Tower Reviewer
|
|
41
|
+
description: Read-only independent reviewer for a completed Tower mission.
|
|
42
|
+
order: 61
|
|
43
|
+
plugins:
|
|
44
|
+
- id: tower-reviewer-policy
|
|
45
|
+
name: 'dsh-tower/reviewer'
|
|
46
|
+
- id: tower-reviewer-fs
|
|
47
|
+
name: '@deepseek-ai/dsh-tool-fs'
|
|
48
|
+
config:
|
|
49
|
+
write: false
|
|
50
|
+
edit: false
|
|
51
|
+
readImage: false
|
|
52
|
+
- id: tower-reviewer-fs-search
|
|
53
|
+
name: '@deepseek-ai/dsh-tool-fs-search'
|
|
54
|
+
config:
|
|
55
|
+
sampleOverCapGlobResults: false
|
package/docs/README.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# dsh-tower documentation
|
|
2
|
+
|
|
3
|
+
English is the source of truth; a Chinese translation lives in [zh/README.md](zh/README.md).
|
|
4
|
+
|
|
5
|
+
Choose a path:
|
|
6
|
+
|
|
7
|
+
| You are | Start here |
|
|
8
|
+
|---|---|
|
|
9
|
+
| New user | [Quick start](guide/quickstart.md) → [Tools](reference/tools.md) → [Example](examples/first-mission.md) |
|
|
10
|
+
| Operator | [Runbook](operations/runbook.md) → [Blockers](reference/blockers.md) → [Error codes](reference/errors.md) → [Events](reference/events.md) → [Doctor](reference/doctor.md) → [Testing](reference/testing.md) → [Batches/leases/legacy](reference/operations.md) → [Security](operations/security.md) |
|
|
11
|
+
| Maintainer | [Architecture](architecture/overview.md) → [Config](reference/config.md) → [Hot reload](guide/hot-reload.md) → [Contributing](../CONTRIBUTING.md) |
|
|
12
|
+
|
|
13
|
+
Reference pages are the source of truth for the current release; the [tools reference](reference/tools.md),
|
|
14
|
+
[blocker list](reference/blockers.md) and [error codes](reference/errors.md) are checked against the
|
|
15
|
+
implementation by `npm run docs:check` in CI (including the Chinese pages).
|
|
16
|
+
|
|
17
|
+
Other useful pages: [Install, upgrade and migration](guide/install-upgrade-migration.md), [Hot reload](guide/hot-reload.md), [FAQ](faq.md), [CHANGELOG](../CHANGELOG.md).
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Architecture and state machine
|
|
2
|
+
|
|
3
|
+
## Components
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
Host plugin (index.js)
|
|
7
|
+
├─ /tower command + Tower mode (guard, prompt section, tower_mode/tower_control, /tower reload)
|
|
8
|
+
├─ lib/tools.js -> 19 repository tools incl. tower_diff, tower_findings and tower_interrupt
|
|
9
|
+
│ (+ tower_reload while dev.hotReload is on; fails reload-unavailable without HMR)
|
|
10
|
+
└─ lib/tower.js -> Tower domain: missions, gates, worktrees, roster, review, findings, merge
|
|
11
|
+
├─ lib/git.js minimal git port (execFile, bounded output, timeout classification)
|
|
12
|
+
├─ lib/store.js repo-scoped lock + atomic JSON + activity.jsonl
|
|
13
|
+
├─ lib/config.js Config schema + profile/repo layers + runtime snapshot
|
|
14
|
+
├─ lib/errors.js stable tool error codes and classification
|
|
15
|
+
├─ lib/workspaceLock.js optional one-Tower-session-per-repository advisory lock
|
|
16
|
+
├─ lib/hmr.js optional DSH HMR bridge (tower_reload / /tower reload)
|
|
17
|
+
└─ lib/modeStore.js per-agent Tower mode persistence
|
|
18
|
+
Subagents
|
|
19
|
+
├─ tower-worker (dsh-tower/worker) read/write/edit/pwsh + mission tools + findings
|
|
20
|
+
└─ tower-reviewer (dsh-tower/reviewer) read/glob/grep + tower_diff + review/finding (read-only)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The main checkout is the control-tower repo; each mission has a branch `tower/<id>-<slug>` and a
|
|
24
|
+
worktree in `.dsh-tower-worktrees/<hash>/<missionId>`. The plugin never operates on the main checkout's
|
|
25
|
+
working tree except merge and the read-only diff.
|
|
26
|
+
|
|
27
|
+
## Mission state machine
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
planned ──spawn worker──▶ active ──tower_complete──▶ completed ──tower_merge──▶ merged
|
|
31
|
+
│ │ ▲ │
|
|
32
|
+
│ │ └──── review round not clean ────┐
|
|
33
|
+
└── abandon ──▶ abandoned│ │
|
|
34
|
+
├── blocker ──▶ blocked ──active/completed──▶ ...
|
|
35
|
+
└── pause ─────▶ paused ──active──▶ ...
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`merged` and `abandoned` are terminal. `tower_mission` may set `blocked → completed`; `merged` is only
|
|
39
|
+
set by `tower_merge`/reconciliation.
|
|
40
|
+
|
|
41
|
+
## Gate pipeline (`tower_preflight`)
|
|
42
|
+
|
|
43
|
+
1. Mission status must be `completed`; tasks and blockers are checked.
|
|
44
|
+
2. The worktree exists; the base tip is an ancestor of the branch tip; changed files are computed
|
|
45
|
+
against the merge base.
|
|
46
|
+
3. Survey missions must not change files; build missions must stay inside `scope`.
|
|
47
|
+
4. The main checkout must be clean for the files this merge would overwrite and on the base branch.
|
|
48
|
+
5. Dependency missions must be merged/abandoned.
|
|
49
|
+
6. A review must exist, belong to this mission, be clean, approve merge, and be bound to the tip
|
|
50
|
+
(unless a clean rebase waived it). No worker may be running.
|
|
51
|
+
|
|
52
|
+
## Merge
|
|
53
|
+
|
|
54
|
+
`tower_merge` runs `git merge --no-ff` with a configurable timeout (default 15 min) and 64 MB buffer.
|
|
55
|
+
After the command, regardless of exit status, it inspects `HEAD`:
|
|
56
|
+
|
|
57
|
+
- merge commit with parents `[baseTip, branchTip]` → record merged (including `recoveredFromFailure`);
|
|
58
|
+
- otherwise classify the failure: unmerged index → `merge-conflict` (mission blocked); no unmerged
|
|
59
|
+
entries → `merge-hook-failed` (mission retryable), with abort/reset cleanup.
|
|
60
|
+
- If the branch or its reviewed commit is already contained in the base, reconcile instead of merging.
|
|
61
|
+
|
|
62
|
+
## State files
|
|
63
|
+
|
|
64
|
+
| Path | Contents |
|
|
65
|
+
|---|---|
|
|
66
|
+
| `<git-common-dir>/dsh-tower/state.json` | missions, roster, reviews, findings, messages, reviews sequence |
|
|
67
|
+
| `<git-common-dir>/dsh-tower/activity.jsonl` | append-only activity |
|
|
68
|
+
| `<git-common-dir>/dsh-tower/state.lock` | single-writer lock (stale locks are reported, never stolen) |
|
|
69
|
+
| `<checkout parent>/.dsh-tower-worktrees/<hash>/<missionId>` | mission worktree |
|
|
70
|
+
| `$DSH_HOME/tower-mode/modes.json` | Tower mode per agent/session |
|