tianshu-mcp 0.7.5 → 0.7.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.en.md +80 -0
- package/CHANGELOG.md +68 -0
- package/README.en.md +38 -27
- package/README.md +38 -27
- package/dist/agents/zcode/cdp.js +128 -22
- package/dist/agents/zcode/model.js +100 -2
- package/dist/agents/zcode/run.js +244 -26
- package/dist/agents/zcode/selectors.js +22 -4
- package/dist/config/schema.js +40 -0
- package/dist/mcp/handlers.js +102 -6
- package/dist/mcp/tools.js +16 -2
- package/dist/server.js +7 -4
- package/dist/tasks/task-manager.js +14 -0
- package/dist/tasks/task.js +13 -0
- package/dist/tasks/wait.js +67 -0
- package/dist/version.generated.js +1 -1
- package/docs/wait-task.en.md +142 -0
- package/docs/wait-task.md +142 -0
- package/package.json +3 -1
- package/skills/tianshu-mcp/SKILL.md +12 -6
- package/skills/tianshu-mcp/usage-examples.md +58 -1
package/CHANGELOG.en.md
CHANGED
|
@@ -8,6 +8,86 @@ Chinese version: [CHANGELOG.md](CHANGELOG.md)
|
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
+
## [0.7.7] - 2026-10-01
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **Blocking wait primitives `wait_task` / `wait_any` (issue #28)**. `run_task` returning a `taskId` immediately is the right adaptation to the host's constraints, but the intended caller (a Tianshu agent session) is **turn-driven** — it runs only within the turn that received a user message and does nothing between turns, so it cannot poll on its own. The task-completion moment could therefore only be caught by a human sending another message. Two **pure read-only, approval-free** tools now carry the waiting:
|
|
16
|
+
- `wait_task(taskId, timeoutMs?)` — block until a single task reaches a **stop point** (terminal status or `needs_user`) or the timeout elapses;
|
|
17
|
+
- `wait_any(taskIds, timeoutMs?)` — wait for the **first task in array order** among a group (1..20) to reach a stop point, returning its snapshot plus every task's current status.
|
|
18
|
+
- **Stop-point definition** (single decision point `isWaitSettled`): `isTerminal(status) || status === "needs_user"`. The moment a task **stops making progress** is the moment to wake the caller — `needs_user` is not terminal but has stopped awaiting a human (it can be resumed by `continue_task` and may re-enter); without waiting for it the wait would block until the timeout and the caller would know nothing about "the task is waiting for a person".
|
|
19
|
+
- **Timeout policy**: `timeoutMs` defaults to `50000ms` (below the common 60 s client tool timeout, leaving round-trip headroom) and caps at `600000ms`; values above the cap are **clamped and disclosed honestly** (never silently rewritten); a timed-out response steers the caller into a call loop (≈50 s per round; long tasks need several calls).
|
|
20
|
+
- **Lossless guarantee**: the wait is **read-only** — it writes no task state and touches no task body, so a client truncation / connection drop / timeout **never affects the task's continued execution**. On request cancellation / connection close the loop exits immediately via the SDK's `extra.signal`, leaking no background wait.
|
|
21
|
+
- **Tool surface 11 → 13** (`read` family +2); new bilingual [wait primitives](docs/wait-task.en.md) doc.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- The `registerTool` callback in `src/server.ts` forwards the SDK request `extra` (including `signal`) to the handler — **used only by the wait tools**; every other handler is unchanged.
|
|
26
|
+
- `MetaBlockFields` gains optional `waitSettled` (whether a stop point was reached) and `waitedMs` (actual wait duration) for programmatic checks by the caller.
|
|
27
|
+
|
|
28
|
+
### Tests
|
|
29
|
+
|
|
30
|
+
- Added `test/unit/wait-task.test.ts` (8 cases: stop-point decision / state transition / timeout / `signal` abort / missing reporting / clamp disclosure) and `test/integration/wait-task.test.ts` (6 cases: real stub long-task end-to-end / short-timeout continuation / not-found error / `cancel_task` effective during a wait / `wait_any` first settled / fail-closed on a missing id).
|
|
31
|
+
- `test/protocol/protocol.test.ts` truth table and tool-name array synced to 13 (the count hard assertion covers it automatically).
|
|
32
|
+
- Full suite **1447 passed / 12 skipped** (1459 tests, 122 files).
|
|
33
|
+
|
|
34
|
+
## [0.7.6] - 2026-09-30
|
|
35
|
+
|
|
36
|
+
### Fixed
|
|
37
|
+
|
|
38
|
+
- **Three ZCode adapter defects (issue #27), reproduced and fixed on real ZCode `3.14.3.7762` (Windows)**:
|
|
39
|
+
- **Split project-collection channels causing a binding deadlock**: on 3.14.3 the
|
|
40
|
+
`[data-testid^="workspace-item-"]` nodes are **not gone from the DOM** — they are scrolled out of
|
|
41
|
+
the viewport instead (measured on the real machine: **40 of 42 nodes invisible**). The old
|
|
42
|
+
implementation collected them without any visibility filter, so the ghost entries made
|
|
43
|
+
`if (!out.length)` permanently false and the only trustworthy channel (the dropdown menu) never
|
|
44
|
+
ran. `matchZcodeProject` then matched a ghost item, the working auto-import branch was skipped,
|
|
45
|
+
and the task died with `project_mismatch`. `projects()` now filters the legacy channel by
|
|
46
|
+
visibility, **always merges both channels**, and lets same-named menu items override sidebar
|
|
47
|
+
entries (only the menu's `aria-checked` is binding evidence rendered by ZCode itself).
|
|
48
|
+
- **Fall back to import when clicks never land**: `clickProject` now reports a distinguishable
|
|
49
|
+
reason (`trigger-unavailable` / `not-found` / `not-visible`). When the target is listed but not a
|
|
50
|
+
single click ever landed, the adapter falls back to the `selectZcodeFolder` import path instead
|
|
51
|
+
of declaring failure (still fail-closed when `allowCreateProject=false`).
|
|
52
|
+
- **Runtime CDP disconnects no longer declare death**: a single `Runtime.evaluate` timeout or an
|
|
53
|
+
endpoint hiccup does not mean CDP is dead (in the reported incident the agent kept writing
|
|
54
|
+
artifacts after MCP had already failed the task). The send phase and the runtime loop now share
|
|
55
|
+
one guard: the first disconnect reconnects **once, for observation only** (matching the existing
|
|
56
|
+
`codex`/`qoder` pattern — **never resending the task**); a failed reconnect or a second
|
|
57
|
+
disconnect lands on `needs_user(setup_recovery)` with both facts attached — whether the process
|
|
58
|
+
is still alive and whether the window still shows running signals — so "still running" is never
|
|
59
|
+
misread as "stopped".
|
|
60
|
+
- **`reasoningLevel` implemented end to end**: the tier set **varies per model**, so it is read
|
|
61
|
+
from the UI **after the model is confirmed** and validated. Out-of-range tiers and unreadable
|
|
62
|
+
tier sets are rejected **before sending** (`reasoning_level_invalid`) instead of silently reusing
|
|
63
|
+
the current value; omitting the tier never touches the UI. Real-machine contract:
|
|
64
|
+
trigger `chat-thought-level-select-trigger` (combobox), options
|
|
65
|
+
`chat-thought-level-select-item-{enabled,disabled}` (binary on/off), options mounted only while
|
|
66
|
+
the menu is open.
|
|
67
|
+
- **Root cause of the "two-level model menu is flaky" symptom**: model items live in the provider
|
|
68
|
+
group's **second-level submenu**, which renders only on **hover** — clicking selects the group
|
|
69
|
+
itself or collapses the menu. The provider group testid has also drifted to
|
|
70
|
+
`chat-model-select-group-registry-provider:`. Group expansion now uses hover
|
|
71
|
+
(`clickExact(..., "hover")`), and when two rounds both yield an empty candidate list the menu is
|
|
72
|
+
reopened for one more round instead of declaring `model_unavailable`.
|
|
73
|
+
- **Permission-menu contract drift (surfaced by the real-machine run, fixed as the same class of defect)**:
|
|
74
|
+
on 3.14.3 the permission items use `menuitemradio` / `menuitemcheckbox` (**not** `option`), and the
|
|
75
|
+
visible name lives in the item's **direct text node**, followed by an explanatory sentence
|
|
76
|
+
(e.g. "Full access — fewer confirmations."). Both mismatched the old implementation and stalled
|
|
77
|
+
dispatch at `permission_unknown`. The selector now carries a role-agnostic fallback, and
|
|
78
|
+
`clickExact` resolves labels from direct text nodes first.
|
|
79
|
+
|
|
80
|
+
### Real-machine verification
|
|
81
|
+
|
|
82
|
+
- `npm run probe:zcode -- dom-contracts`: `workspaceItems=42` (2 visible / 40 invisible),
|
|
83
|
+
`dataProjectPath=0`; with the menu open `projects()` returns the menu items with correct checked
|
|
84
|
+
state — independently reproducing both the issue's geometric premise and the fixed collection.
|
|
85
|
+
- `npm run probe:zcode -- models` / `permission` plus one-off probes: pinned the provider-group hover
|
|
86
|
+
semantics, the permission item role/text structure, and the binary tier shape
|
|
87
|
+
(`current=on`, `tiers=Off/On`).
|
|
88
|
+
- `npm run smoke:zcode`: end-to-end real-machine dispatch (project binding → model switch →
|
|
89
|
+
permission confirm → send → poll to terminal state).
|
|
90
|
+
|
|
11
91
|
## [0.7.5] - 2026-09-29
|
|
12
92
|
|
|
13
93
|
### Fixed
|
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,74 @@
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## [0.7.7] - 2026-10-01
|
|
11
|
+
|
|
12
|
+
### 新增
|
|
13
|
+
|
|
14
|
+
- **阻塞等待原语 `wait_task` / `wait_any`(issue #28)**。`run_task` 秒回 `taskId` 是对宿主约束的正确适配,
|
|
15
|
+
但目标调用方(天枢 agent 会话)**回合驱动**——只在收到用户消息的回合内运行、回合之间不运行,无法自行轮询,
|
|
16
|
+
于是「任务完成时刻」只能靠人工再发一条消息触发查询。新增两个**纯只读、免审批**工具承载「等」:
|
|
17
|
+
- `wait_task(taskId, timeoutMs?)`:阻塞等待单任务到达**停点**(终态或 `needs_user`)或超时;
|
|
18
|
+
- `wait_any(taskIds, timeoutMs?)`:等待一组任务(1..20)中**数组顺序首个**到达停点者,返回其快照 + 全部任务当前状态。
|
|
19
|
+
- **停点定义**(单一判定点 `isWaitSettled`):`isTerminal(status) || status === "needs_user"`。任务**停止推进**的时刻即应唤醒调用方——
|
|
20
|
+
`needs_user` 虽非终态但已停等人工(可被 `continue_task` 恢复,之后可能再次进入),不等它会空等到超时,调用方对「任务在等人」一无所知。
|
|
21
|
+
- **超时策略**:`timeoutMs` 缺省 `50000ms`(低于生态常见 60s 客户端超时,留序列化/往返余量)、上限 `600000ms`,
|
|
22
|
+
显式超上限的值**钳制并如实披露**(不静默改值);超时返回体引导循环调用(每轮 ≈50s,长任务靠多次调用)。
|
|
23
|
+
- **无损保证**:等待是**纯只读**的——不写任务状态、不动任务本体;被客户端截断 / 连接中断 / 超时都**不影响任务继续执行**。
|
|
24
|
+
请求取消 / 连接关闭时经 SDK 的 `extra.signal` **立即退出**循环,不泄漏后台等待。
|
|
25
|
+
- **工具面 11 → 13**(`read` 族 +2);新增 [等待原语](docs/wait-task.md) 双语文档。
|
|
26
|
+
|
|
27
|
+
### 变更
|
|
28
|
+
|
|
29
|
+
- `src/server.ts` 的 `registerTool` 回调把 SDK 的请求 `extra`(含 `signal`)透传给 handler——**仅 wait 工具使用**,其余 handler 行为不变。
|
|
30
|
+
- `MetaBlockFields` 新增可选字段 `waitSettled`(是否到停点)与 `waitedMs`(实际等待时长),供调用方可编程判断。
|
|
31
|
+
|
|
32
|
+
### 测试
|
|
33
|
+
|
|
34
|
+
- 新增 `test/unit/wait-task.test.ts`(8 例:停点判定 / 状态跃迁 / 超时 / `signal` 中止 / 缺失上报 / 钳制披露)
|
|
35
|
+
与 `test/integration/wait-task.test.ts`(6 例:真实 stub 长任务端到端 / 短超时续等 / 不存在报错 / 等待期间 `cancel_task` 即时生效 / `wait_any` 先停者 / 缺一即报错)。
|
|
36
|
+
- `test/protocol/protocol.test.ts` 真值表与工具面名字数组同步为 13(数量硬断言自动覆盖)。
|
|
37
|
+
- 全量 **1447 passed / 12 skipped**(1459 项,122 文件)。
|
|
38
|
+
|
|
39
|
+
## [0.7.6] - 2026-09-30
|
|
40
|
+
|
|
41
|
+
### 修复
|
|
42
|
+
|
|
43
|
+
- **ZCode 适配器三项缺陷(issue #27),已在真机 ZCode `3.14.3.7762`(Windows)上复现并修复**:
|
|
44
|
+
- **项目采集渠道分裂导致绑定死锁**:3.14.3 上 `[data-testid^="workspace-item-"]` **并未从 DOM 消失**,
|
|
45
|
+
只是被滚出视口(真机实测 **42 个节点中 40 个不可见**)。旧实现采集时不做可见性过滤,幽灵项入列使
|
|
46
|
+
`if (!out.length)` 短路恒为假,唯一可信的菜单渠道永不执行 → `matchZcodeProject` 命中幽灵项 →
|
|
47
|
+
可用的自动导入分支被跳过 → 任务卡死在 `project_mismatch`。现在 `projects()` 对旧契约项做可见性过滤、
|
|
48
|
+
两条渠道**始终合并**,且同名的菜单项覆盖侧边栏项(只有菜单的 `aria-checked` 是 ZCode 自己渲染的绑定证据)。
|
|
49
|
+
- **点击落空时回落导入**:`clickProject` 现在返回可区分的原因(`trigger-unavailable` / `not-found` /
|
|
50
|
+
`not-visible`);目标项在列表里却一次都没真正点中时,回落 `selectZcodeFolder` 导入路径而不是直接判死
|
|
51
|
+
(`allowCreateProject=false` 时仍在下一道闸门 fail-closed)。
|
|
52
|
+
- **运行期 CDP 断连不再判死**:单次 `Runtime.evaluate` 超时或端点抖动不等于 CDP 已死(issue 现场是
|
|
53
|
+
「MCP 判定失败后 agent 仍在写产物」)。发送阶段与运行期统一护栏:首次断连重连**观察一次**
|
|
54
|
+
(对齐 `codex`/`qoder` 的既有范式,重连只用于观察、**绝不重发任务**),重连失败或再次断连落
|
|
55
|
+
`needs_user(setup_recovery)`,并附「进程是否仍在」「窗口是否仍有运行信号」两侧事实,避免把「仍在跑」
|
|
56
|
+
误读成「已停」。
|
|
57
|
+
- **`reasoningLevel` 端到端实现**:档位集合**随模型变化**,因此在**模型确认之后**才读取界面实际渲染的选项
|
|
58
|
+
并校验;越权档位与「集合读不到」都在**发送前**报错(`reasoning_level_invalid`),绝不静默沿用;
|
|
59
|
+
未指定档位时完全不触碰界面。真机契约:触发器 `chat-thought-level-select-trigger`(combobox),
|
|
60
|
+
选项 `chat-thought-level-select-item-{enabled,disabled}`(二值 开启/关闭),选项只在菜单展开时挂载。
|
|
61
|
+
- **「两级模型菜单点击不稳」根因**:模型项在 provider 分组的**二级子菜单**里,**必须 hover 分组**才渲染,
|
|
62
|
+
用 click 会选中分组本身或收起菜单;provider 分组 testid 也已漂移为
|
|
63
|
+
`chat-model-select-group-registry-provider:`。现在展开分组改用 hover(`clickExact(..., "hover")`),
|
|
64
|
+
并在两轮候选皆空时把菜单重开一次再试一轮,不凭一轮空列表判 `model_unavailable`。
|
|
65
|
+
- **权限菜单契约漂移(真机测试暴露,同类问题一并修复)**:3.14.3 的权限项 role 是
|
|
66
|
+
`menuitemradio` / `menuitemcheckbox`(**不是** `option`),且可见名写在项内的**直接文本节点**里、
|
|
67
|
+
后面还跟一句说明(如「完全访问减少确认次数。」)。旧实现两处都会 0 命中,导致派发卡在 `permission_unknown`。
|
|
68
|
+
候选选择器补无 role 限制的兜底,`clickExact` 的标签解析优先取直接文本节点。
|
|
69
|
+
|
|
70
|
+
### 真机验证
|
|
71
|
+
|
|
72
|
+
- `npm run probe:zcode -- dom-contracts`:`workspaceItems=42`(可见 2 / 不可见 40)、`dataProjectPath=0`、
|
|
73
|
+
菜单展开后 `projects()` 返回菜单项且勾选态正确 —— 独立复现了 issue 的几何前提与修复后的采集结果。
|
|
74
|
+
- `npm run probe:zcode -- models` / `permission` 与一次性探针:锁定 provider 分组 hover 语义、
|
|
75
|
+
权限项 role 与文本结构、档位二值形态(`current=on`、`tiers=Off/On`)。
|
|
76
|
+
- `npm run smoke:zcode`:真机端到端派发(项目绑定 → 模型切换 → 权限确认 → 发送 → 轮询终态)。
|
|
77
|
+
|
|
10
78
|
## [0.7.5] - 2026-09-29
|
|
11
79
|
|
|
12
80
|
### 修复
|
package/README.en.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<img src="./assets/tianshu-mcp-banner.svg" alt="Tianshu Orchestration MCP tianshu-mcp" width="100%">
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
|
-
<h1 align="center">Tianshu Orchestration MCP
|
|
5
|
+
<h1 align="center">Tianshu Orchestration MCP tianshu-mcp</h1>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
8
|
<b>Dispatch with agents, verify with evidence. · 把开发交给 AI-Agent,把验收交给运行时</b>
|
|
@@ -30,7 +30,6 @@
|
|
|
30
30
|
<p align="center">
|
|
31
31
|
<img src="https://img.shields.io/github/actions/workflow/status/lanlan0811/tianshu-mcp/ci.yml?branch=master&style=for-the-badge&logo=github&label=CI" alt="CI">
|
|
32
32
|
<img src="https://img.shields.io/npm/v/tianshu-mcp?style=for-the-badge&logo=npm&logoColor=white&label=npm&color=cb3837" alt="npm version">
|
|
33
|
-
<img src="https://img.shields.io/npm/dm/tianshu-mcp?style=for-the-badge&logo=npm&logoColor=white&label=downloads&color=cb3837" alt="npm downloads">
|
|
34
33
|
<img src="https://img.shields.io/github/stars/lanlan0811/tianshu-mcp?style=for-the-badge&logo=github&label=stars&color=24292e" alt="GitHub stars">
|
|
35
34
|
<img src="https://img.shields.io/badge/License-Apache%202.0-3B5BDB?style=for-the-badge&logo=apache" alt="License">
|
|
36
35
|
<img src="https://img.shields.io/badge/TypeScript-5.7-3178c6?style=for-the-badge&logo=typescript&logoColor=white" alt="TypeScript">
|
|
@@ -39,8 +38,20 @@
|
|
|
39
38
|
<img src="https://img.shields.io/badge/Tests-1383%20Passed-green?style=for-the-badge" alt="Tests">
|
|
40
39
|
</p>
|
|
41
40
|
|
|
41
|
+
<p align="center">
|
|
42
|
+
<a href="https://www.npmjs.com/package/tianshu-mcp"><img src="https://img.shields.io/npm/d18m/tianshu-mcp?style=for-the-badge&logo=npm&logoColor=white&label=mcp%20downloads&color=cb3837" alt="MCP downloads (npm)"></a>
|
|
43
|
+
<a href="https://github.com/lanlan0811/tianshu-mcp/releases?q=v&expanded=true"><img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2Flanlan0811%2Ftianshu-mcp%2Fmaster%2Fupdate%2Fstats.json&query=%24.mcpDownloads&style=for-the-badge&logo=github&logoColor=white&label=mcp%20tarball%20downloads&color=2ea44f" alt="MCP tarball downloads (GitHub releases)"></a>
|
|
44
|
+
<a href="https://github.com/lanlan0811/tianshu-mcp/releases?q=gui-v&expanded=true"><img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2Flanlan0811%2Ftianshu-mcp%2Fmaster%2Fupdate%2Fstats.json&query=%24.guiDownloads&style=for-the-badge&logo=github&logoColor=white&label=gui%20downloads&color=1f6feb" alt="Log viewer GUI downloads (GitHub releases)"></a>
|
|
45
|
+
</p>
|
|
46
|
+
|
|
42
47
|
---
|
|
43
48
|
|
|
49
|
+
<p align="center">
|
|
50
|
+
<img src="./assets/mcp-running.png" alt="Tianshu Harness desktop orchestrating ZCode through tianshu-mcp" width="100%">
|
|
51
|
+
<br>
|
|
52
|
+
Tianshu Harness desktop in action — <b>Tianshu</b> calls <b>tianshu-mcp</b> over MCP to orchestrate <b>ZCode</b> through a development task: tasks dispatched and tracked on the left, tianshu-mcp tool calls and event stream in the middle (<code>mcp__tianshu-mcp__query_task</code> polling a running task), and ZCode doing the actual work on the right
|
|
53
|
+
</p>
|
|
54
|
+
|
|
44
55
|
### An orchestration layer and objective acceptance gate for AI agents
|
|
45
56
|
|
|
46
57
|
> **tianshu-mcp** is an orchestration layer plugged into **Tianshu** as a standard MCP server. Tianshu is the commander and the user-facing surface; this server does three jobs: **scheduling** (queues / concurrency gate / state machine / cancellation), the **execution surface** (delivering task briefs to external AI agents), and the **objective acceptance gate** (command checks, code analysis and optional visual comparison, all relative to a git baseline).
|
|
@@ -57,8 +68,9 @@ Codex · TraeWork · ZCode · Kimi Code · Qoder CN · Open Design
|
|
|
57
68
|
target project workspace ← git repo + tests + .tianshu-mcp/
|
|
58
69
|
```
|
|
59
70
|
|
|
60
|
-
- **
|
|
61
|
-
- **Async contract — long tasks never block `tools/call`** — `run_task` returns a `taskId` immediately
|
|
71
|
+
- **13 MCP tools** — `run_task / continue_task / query_task / list_tasks / get_task_report / cancel_task / verify_task / rework_task / get_profiles / wait_task / wait_any`, plus `prepare_visual_baseline / approve_visual_baseline` for visual acceptance.
|
|
72
|
+
- **Async contract — long tasks never block `tools/call`** — `run_task` returns a `taskId` immediately, then `wait_task` blocks until a stop point (terminal status or `needs_user`), or `query_task` polls; progress is persisted, never pushed, so the caller always sees "the last fact written to disk".
|
|
73
|
+
- **Wait primitives (issue #28)** — `wait_task(taskId)` / `wait_any(taskIds)` return in a single call once a task reaches a **stop point** (terminal status or `needs_user`), designed for turn-driven callers: dispatch with `run_task` and wait for the result within the same turn, no hand-rolled polling. Read-only; timeouts or interruptions never affect the task itself.
|
|
62
74
|
- **Objective acceptance, fail-closed** — automated command checks plus programmatic code analysis, all relative to the **git baseline captured before work started**, and the server **never auto-commits / stashes / rolls back**. A test check that exits 0 with zero executed tests, or a git project with zero net changes, fails rather than passing green.
|
|
63
75
|
- **Rework loop** — automatic rework (`autoFixRounds`) plus manual `rework_task`; failure reasons are parsed into **directly executable actions** and fed back to the agent, and exhausted rounds become `needs_attention` awaiting a Tianshu verdict.
|
|
64
76
|
- **Six GUI execution surfaces (CDP)** — each agent uses an isolated CDP flow to drive its desktop UI and reports fine-grained events at key nodes, so `query_task` can tell "the agent is working" apart from "stuck on a dialog waiting for a human".
|
|
@@ -114,7 +126,7 @@ The shape of this project is not a free design: it was forced by a handful of **
|
|
|
114
126
|
|
|
115
127
|
## Core features
|
|
116
128
|
|
|
117
|
-
- **Async dispatch and
|
|
129
|
+
- **Async dispatch and waiting** — `run_task` returns a `taskId` immediately; `wait_task` blocks until a task reaches a stop point (terminal status or `needs_user`) and `wait_any` waits for the first of a group; use `query_task` for progress detail — status / progress / log tail / recent fine-grained events (`eventLimit`, 1..50, default 10). See [wait primitives](docs/wait-task.en.md).
|
|
118
130
|
- **Objective acceptance engine** — automated command checks (typecheck/lint/test/build, skipped when absent, plus tech-stack derivation) plus programmatic code analysis (changed-file list / diffstat / suspicious signals such as TODO, debugger, secret-like patterns), all relative to the **git baseline**; command checks run **bounded-parallel** by default (`verifyConcurrency`, default 2, range 1–4; `1` makes them fully serial).
|
|
119
131
|
- **Three fail-closed guards** — a test check fails when its output reports zero executed tests even if the exit code is 0; git projects must produce changes relative to the baseline by default (pure analysis tasks opt out with `"requireChanges": false` in `.tianshu-mcp/acceptance.json`); a round cancelled at any point yields `passed=false`.
|
|
120
132
|
- **Three-level acceptance config inheritance** (issue #20) — `<data-dir>/acceptance.default.json` (global fallback) → `<project>/.tianshu-mcp/acceptance.json` (project override) → the `acceptanceOverride` argument (transient task override, never written to disk). Inspect the effective configuration with `tianshu-mcp config acceptance <projectPath> [--task <id>]`. See the [acceptance config spec](docs/acceptance-config.en.md).
|
|
@@ -172,10 +184,10 @@ In Tianshu, go to **Settings → MCP servers → Add** and fill in the fields be
|
|
|
172
184
|
| Command | `npx` | `node` |
|
|
173
185
|
| Arguments (space-separated) | `-y tianshu-mcp` | `<absolute-repo-path>/dist/index.js` |
|
|
174
186
|
|
|
175
|
-
> - The server ID is the tool prefix: with `tianshu-mcp` the tools are `mcp__tianshu-mcp__run_task` and the other
|
|
187
|
+
> - The server ID is the tool prefix: with `tianshu-mcp` the tools are `mcp__tianshu-mcp__run_task` and the other 12.
|
|
176
188
|
> - Arguments are space-separated with **no quotes**; in local development replace `<absolute-repo-path>` with a real absolute path.
|
|
177
189
|
> - The UI has no environment-variable field; to override the data directory, use the `config.json` route below to set `TIANSHU_MCP_HOME`.
|
|
178
|
-
> - Once the connection succeeds you are done; a new session shows all
|
|
190
|
+
> - Once the connection succeeds you are done; a new session shows all 13 tools.
|
|
179
191
|
|
|
180
192
|
### Or edit config.json (environment variables supported)
|
|
181
193
|
|
|
@@ -193,23 +205,24 @@ In Tianshu, go to **Settings → MCP servers → Add** and fill in the fields be
|
|
|
193
205
|
}
|
|
194
206
|
```
|
|
195
207
|
|
|
196
|
-
After opening a new session the tool surface exposes `mcp__tianshu-mcp__run_task` and the other
|
|
208
|
+
After opening a new session the tool surface exposes `mcp__tianshu-mcp__run_task` and the other 12 tools. One typical loop:
|
|
197
209
|
|
|
198
210
|
```text
|
|
199
211
|
run_task(projectPath=D:/xxx/my-app, task="…task brief…", agentId=codex,
|
|
200
212
|
model="GPT-5.6 Sol", reasoningLevel="high", autoVerify=true, autoFixRounds=5)
|
|
201
|
-
→ taskId →
|
|
213
|
+
→ taskId → wait_task(taskId) blocks until a stop point → succeeded / failed / needs_attention → read get_task_report
|
|
214
|
+
(turn-driven callers: one wait_task call returns at the stop point; after a timeout call it again to keep waiting, or use query_task for progress detail)
|
|
202
215
|
```
|
|
203
216
|
|
|
204
217
|
### Prompts to give Tianshu (recommended usage)
|
|
205
218
|
|
|
206
|
-
> "In project `D:\xxx`, use codex to implement 『task』. First run `run_task(autoVerify:true, autoFixRounds:2)`, then
|
|
219
|
+
> "In project `D:\xxx`, use codex to implement 『task』. First run `run_task(autoVerify:true, autoFixRounds:2)`, then `wait_task` until it reaches a stop point; if the report shows `needs_attention`, pass the failure summary from `get_task_report` as `feedback` to `rework_task` for another round; when everything passes, report `changedFiles` and `diffstat` back to me."
|
|
207
220
|
|
|
208
221
|
> "In project `D:\xxx`, use traework with `mode=Code` to implement 『task』; it switches to Code mode, binds the project, sends the task, verifies automatically, and on failure generates a repair plan and reworks."
|
|
209
222
|
|
|
210
223
|
## Tool surface
|
|
211
224
|
|
|
212
|
-
|
|
225
|
+
13 tools, split into three capability families: `read` (read/query, no side effects), `write` (side effects, all requiring approval), and `execute` (runs project-side commands without changing source; currently only `verify_task`, still approval-free).
|
|
213
226
|
|
|
214
227
|
| Tool | Capability / approval | Purpose |
|
|
215
228
|
|---|---|---|
|
|
@@ -220,6 +233,8 @@ run_task(projectPath=D:/xxx/my-app, task="…task brief…", agentId=codex,
|
|
|
220
233
|
| `get_task_report` | read | Full text of one round's acceptance report (`report.md`) |
|
|
221
234
|
| `cancel_task` | write + approval | Cancel a running task: CLI agents kill the process tree; GUI agents best-effort click stop over CDP and wait boundedly within `gui.cancelWaitMs` (default 15s); for a terminal GUI task it doubles as the manual confirmation entry |
|
|
222
235
|
| `verify_task` | execute (no source changes, approval-free) | Run acceptance once against a task or a project path. It runs configured commands and may produce build artifacts, so its MCP `readOnlyHint` is `false` — but it **changes no source and still needs no approval**; optional `idempotencyKey` |
|
|
236
|
+
| `wait_task` | read | Block until one task reaches a stop point (terminal status or `needs_user`) or the timeout elapses; `timeoutMs` defaults to 50000, caps at 600000 — call again after a timeout to keep waiting. Read-only, harmless |
|
|
237
|
+
| `wait_any` | read | Block until the first of a group (1..20) reaches a stop point, in array order; returns that task's snapshot plus the current status of every task. Validates all ids exist, failing if any is missing |
|
|
223
238
|
| `rework_task` | write + approval | Manual rework (feeds the failure report back to the same agent); optional `repairHint` (≤4000 chars) |
|
|
224
239
|
| `get_profiles` | read | Show agent adapters and executable discovery results |
|
|
225
240
|
| `prepare_visual_baseline` | write + approval | Capture or import a reference image and produce a candidate and summary for review |
|
|
@@ -236,7 +251,7 @@ run_task(projectPath=D:/xxx/my-app, task="…task brief…", agentId=codex,
|
|
|
236
251
|
| agentId | driver / adapter | status | Notes |
|
|
237
252
|
|---|---|---|---|
|
|
238
253
|
| `codex` | `gui` / `codex-gui` | **ready** (`research` on macOS) | Codex desktop GUI (Windows: MSIX COM activation + CDP; macOS: spawn .app + CDP); supports `model` / `reasoningLevel` / `planDoc` / `designSystem`; user-confirmation wait, cancellation and re-dispatch guards are all machine-verified |
|
|
239
|
-
| `zcode` | `gui` / `zcode-gui` | **
|
|
254
|
+
| `zcode` | `gui` / `zcode-gui` | **ready** (closed-loop verified on real Windows; macOS unverified) | CDP GUI adapter; supports project-less dispatch, `allowCreateProject` and `reasoningLevel` (the tier set **varies per model**; out-of-range tiers fail **before sending**); **v0.7.4 adapted to the missing 3.14.x path contracts** (the binding verdict became "path first, display-name when no path is available + global name disambiguation", failing closed on duplicates); **v0.7.6 fixes the binding deadlock** (sidebar `workspace-item-*` nodes scrolled out of view were still collected, short-circuiting the only trustworthy menu channel), **adds a recovery entry point for runtime CDP disconnects** (reconnect once for observation, never resend; a failed reconnect lands on `needs_user(setup_recovery)`) and **fixes the two-level model menu** (provider groups render their submenu only on hover) |
|
|
240
255
|
| `traework` | `gui` / `traework-gui` | **ready** | CDP-driven TRAE SOLO CN desktop UI; supports `mode` (Work / Code / Design, each of the three modes maintaining its own project binding); all three modes machine-verified |
|
|
241
256
|
| `kimicode` | `gui` / `kimicode-gui` | **ready** (`research` on macOS) | Kimi Code desktop (Electron); **dual renderer processes** (main window plus a `Kimi Browser Overlay` that hosts the model / reasoning / mode menus); workspaces bind by full path; supports `model` / `reasoningLevel`, **not `mode`**, and **not project-less dispatch** |
|
|
242
257
|
| `qoder` | `gui` / `qoder-gui` | closed-loop verified on Windows; **research** on macOS | Qoder CN only; requires an existing `projectPath` and a readable `planDoc`; `modelSource=default\|custom` disambiguates same-named models, and the reasoning level is saved as a global preference via "Model management" and read back |
|
|
@@ -285,7 +300,7 @@ The built-in `codex` drives the desktop GUI; if you would rather not depend on G
|
|
|
285
300
|
|
|
286
301
|
| Capability | Meaning | Approval | Tools |
|
|
287
302
|
|---|---|---|---|
|
|
288
|
-
| `read` | read/query only, no side effects | none | `query_task` / `list_tasks` / `get_task_report` / `get_profiles` |
|
|
303
|
+
| `read` | read/query only, no side effects | none | `query_task` / `list_tasks` / `get_task_report` / `get_profiles` / `wait_task` / `wait_any` |
|
|
289
304
|
| `write` | has side effects | required | `run_task` / `continue_task` / `cancel_task` / `rework_task` / the two visual baseline tools |
|
|
290
305
|
| `execute` | runs project-side commands, changes no source | none | `verify_task` |
|
|
291
306
|
|
|
@@ -384,21 +399,15 @@ Key capabilities:
|
|
|
384
399
|
- **Update-notes window and dual-source auto-update** — a silent update check at startup pops the "update notes" window when a new version is found (download and install / ignore this version / later), whose body is that version's bilingual release notes; the update source is chosen by **concurrently probing Gitee / GitHub and picking the better one** (never relying on system region) and is shown truthfully, and every package is **minisign-verified** — **a failed signature is never installed**.
|
|
385
400
|
|
|
386
401
|
<p align="center">
|
|
387
|
-
<img src="./assets/tianshu-mcp-gui-overview.png" alt="Log viewer · task overview page" width="
|
|
402
|
+
<a href="./assets/tianshu-mcp-gui-overview.png"><img src="./assets/tianshu-mcp-gui-overview.png" alt="Log viewer · task overview page" width="32%"></a>
|
|
403
|
+
<a href="./assets/tianshu-mcp-gui-event-stream.png"><img src="./assets/tianshu-mcp-gui-event-stream.png" alt="Log viewer · task event stream workspace" width="32%"></a>
|
|
404
|
+
<a href="./assets/tianshu-mcp-gui-agent-log.png"><img src="./assets/tianshu-mcp-gui-agent-log.png" alt="Log viewer · agent raw log workspace" width="32%"></a>
|
|
388
405
|
<br>
|
|
389
|
-
<
|
|
390
|
-
</p>
|
|
391
|
-
|
|
392
|
-
<p align="center">
|
|
393
|
-
<img src="./assets/tianshu-mcp-gui-event-stream.png" alt="Log viewer · task event stream workspace" width="88%">
|
|
406
|
+
<b>Task overview page</b> — resident left rail · five-cell metrics (total / running / finished / succeeded / failed) · status chips · task card grid
|
|
394
407
|
<br>
|
|
395
|
-
<
|
|
396
|
-
</p>
|
|
397
|
-
|
|
398
|
-
<p align="center">
|
|
399
|
-
<img src="./assets/tianshu-mcp-gui-agent-log.png" alt="Log viewer · agent raw log workspace" width="88%">
|
|
408
|
+
<b>Full-screen workspace · event stream</b> — line / time / event / detail columns, with status transitions and progress records colour-coded
|
|
400
409
|
<br>
|
|
401
|
-
<
|
|
410
|
+
<b>Full-screen workspace · agent log</b> — level filtering · line numbers and word wrap · "loaded N / M" with "jump to latest"
|
|
402
411
|
</p>
|
|
403
412
|
|
|
404
413
|
Decoupling and release boundaries (read before changing anything here):
|
|
@@ -419,7 +428,8 @@ Decoupling and release boundaries (read before changing anything here):
|
|
|
419
428
|
|
|
420
429
|
| Document | Contents |
|
|
421
430
|
|---|---|
|
|
422
|
-
| [ARCHITECTURE.en.md](ARCHITECTURE.en.md) | Architecture: layering and module boundaries, state machine, acceptance pipeline, driver-layer contracts, extension points, known gaps |
|
|
431
|
+
| [ARCHITECTURE.en.md](<ARCHITECTURE.en.md>) | Architecture: layering and module boundaries, state machine, acceptance pipeline, driver-layer contracts, extension points, known gaps |
|
|
432
|
+
| [docs/core-principles.en.md](<docs/core-principles.en.md>) | Core principles: how four hard constraints forced the current architecture, the core mechanisms one by one, and why they are self-consistent |
|
|
423
433
|
| [docs/tianshu-integration.en.md](docs/tianshu-integration.en.md) | The two Tianshu `config.json` integration modes, UI / API steps, smoke procedure, FAQ |
|
|
424
434
|
| [docs/agent-profiles.en.md](docs/agent-profiles.en.md) | Agent profile field reference plus real-machine samples |
|
|
425
435
|
| [docs/adapter-matrix.en.md](docs/adapter-matrix.en.md) | Capability research matrix for each agent |
|
|
@@ -445,7 +455,8 @@ Decoupling and release boundaries (read before changing anything here):
|
|
|
445
455
|
| [docs/repair-directives.en.md](docs/repair-directives.en.md) | Structured repair directives: sources, fallback semantics, known limits |
|
|
446
456
|
| [docs/dry-run.en.md](docs/dry-run.en.md) | dryRun mode: read-only constraint, zero-change gate, plan document |
|
|
447
457
|
| [docs/event-stream.en.md](docs/event-stream.en.md) | Fine-grained event stream: vocabulary, persistence, bounded read-side window |
|
|
448
|
-
|
|
|
458
|
+
| docs/notifications.en.md | Task terminal-state notifications: webhook contract, de-duplication, signing |
|
|
459
|
+
| docs/wait-task.en.md | Wait primitives: `wait_task` / `wait_any` contract, stop-point definition, timeout matrix and loop patterns |
|
|
449
460
|
| [docs/visual-acceptance.en.md](docs/visual-acceptance.en.md) | Visual acceptance primer and full configuration (including optional AI content validation) |
|
|
450
461
|
| [docs/visual-validation.en.md](docs/visual-validation.en.md) | Visual acceptance validation progress and platform evidence |
|
|
451
462
|
| [docs/visual-validation-evidence/](docs/visual-validation-evidence/) | Raw machine-readable records behind that validation |
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<img src="./assets/tianshu-mcp-banner.svg" alt="天枢编排 MCP tianshu-mcp" width="100%">
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
|
-
<h1 align="center">天枢编排 MCP
|
|
5
|
+
<h1 align="center">天枢编排 MCP tianshu-mcp</h1>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
8
|
<b>把开发交给 AI-Agent,把验收交给运行时 · Dispatch with agents, verify with evidence.</b>
|
|
@@ -30,7 +30,6 @@
|
|
|
30
30
|
<p align="center">
|
|
31
31
|
<img src="https://img.shields.io/github/actions/workflow/status/lanlan0811/tianshu-mcp/ci.yml?branch=master&style=for-the-badge&logo=github&label=CI" alt="CI">
|
|
32
32
|
<img src="https://img.shields.io/npm/v/tianshu-mcp?style=for-the-badge&logo=npm&logoColor=white&label=npm&color=cb3837" alt="npm version">
|
|
33
|
-
<img src="https://img.shields.io/npm/dm/tianshu-mcp?style=for-the-badge&logo=npm&logoColor=white&label=downloads&color=cb3837" alt="npm downloads">
|
|
34
33
|
<img src="https://img.shields.io/github/stars/lanlan0811/tianshu-mcp?style=for-the-badge&logo=github&label=stars&color=24292e" alt="GitHub stars">
|
|
35
34
|
<img src="https://img.shields.io/badge/License-Apache%202.0-3B5BDB?style=for-the-badge&logo=apache" alt="License">
|
|
36
35
|
<img src="https://img.shields.io/badge/TypeScript-5.7-3178c6?style=for-the-badge&logo=typescript&logoColor=white" alt="TypeScript">
|
|
@@ -39,8 +38,20 @@
|
|
|
39
38
|
<img src="https://img.shields.io/badge/Tests-1383%20Passed-green?style=for-the-badge" alt="Tests">
|
|
40
39
|
</p>
|
|
41
40
|
|
|
41
|
+
<p align="center">
|
|
42
|
+
<a href="https://www.npmjs.com/package/tianshu-mcp"><img src="https://img.shields.io/npm/d18m/tianshu-mcp?style=for-the-badge&logo=npm&logoColor=white&label=MCP%20%E4%B8%8B%E8%BD%BD%E6%AC%A1%E6%95%B0&color=cb3837" alt="MCP 下载次数(npm)"></a>
|
|
43
|
+
<a href="https://github.com/lanlan0811/tianshu-mcp/releases?q=v&expanded=true"><img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2Flanlan0811%2Ftianshu-mcp%2Fmaster%2Fupdate%2Fstats.json&query=%24.mcpDownloads&style=for-the-badge&logo=github&logoColor=white&label=MCP%20%E5%8E%8B%E7%BC%A9%E5%8C%85%E4%B8%8B%E8%BD%BD%E6%AC%A1%E6%95%B0&color=2ea44f" alt="MCP 压缩包下载次数(GitHub 发行)"></a>
|
|
44
|
+
<a href="https://github.com/lanlan0811/tianshu-mcp/releases?q=gui-v&expanded=true"><img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2Flanlan0811%2Ftianshu-mcp%2Fmaster%2Fupdate%2Fstats.json&query=%24.guiDownloads&style=for-the-badge&logo=github&logoColor=white&label=GUI%20%E4%B8%8B%E8%BD%BD%E6%AC%A1%E6%95%B0&color=1f6feb" alt="日志台 GUI 下载次数(GitHub 发行)"></a>
|
|
45
|
+
</p>
|
|
46
|
+
|
|
42
47
|
---
|
|
43
48
|
|
|
49
|
+
<p align="center">
|
|
50
|
+
<img src="./assets/mcp-running.png" alt="天枢 harness 桌面端通过 tianshu-mcp 调用 ZCode 完成开发" width="100%">
|
|
51
|
+
<br>
|
|
52
|
+
天枢 harness 桌面端实况 —— <b>天枢</b>经 MCP 调用 <b>tianshu-mcp</b> 编排 <b>ZCode</b> 完成一次开发任务:左侧派发与跟踪任务,中间是 tianshu-mcp 的工具调用与事件流(<code>mcp__tianshu-mcp__query_task</code> 轮询运行中的任务),右侧 ZCode 正在执行实际开发
|
|
53
|
+
</p>
|
|
54
|
+
|
|
44
55
|
### 面向 AI-Agent 的编排层与客观验收仪
|
|
45
56
|
|
|
46
57
|
> **tianshu-mcp** 是被 **天枢(Tianshu)** 当作标准 MCP server 接入的编排层。天枢是总指挥与用户交互面,本 server 承担三件事:**调度**(队列 / 并发闸 / 状态机 / 取消)、**执行面**(把任务书送达外部 AI-Agent)、**客观验收仪**(相对 git 基线做命令检查、代码分析与可选视觉比对)。
|
|
@@ -57,8 +68,9 @@ Codex · TraeWork · ZCode · Kimi Code · Qoder CN · Open Design
|
|
|
57
68
|
目标项目工作区 ← git 仓库 + 测试 + .tianshu-mcp/
|
|
58
69
|
```
|
|
59
70
|
|
|
60
|
-
- **
|
|
61
|
-
- **异步契约,长任务不卡 `tools/call`** —— `run_task` 秒回 `taskId`,用 `query_task` 轮询;进度只落盘、不推送,调用方看到的始终是「最后一次落盘的事实」。
|
|
71
|
+
- **13 个 MCP 工具** —— `run_task / continue_task / query_task / list_tasks / get_task_report / cancel_task / verify_task / rework_task / get_profiles / wait_task / wait_any`,外加视觉验收的 `prepare_visual_baseline / approve_visual_baseline`。
|
|
72
|
+
- **异步契约,长任务不卡 `tools/call`** —— `run_task` 秒回 `taskId`,用 `wait_task` 阻塞等到停点(终态或 `needs_user`)、或用 `query_task` 轮询;进度只落盘、不推送,调用方看到的始终是「最后一次落盘的事实」。
|
|
73
|
+
- **等待原语(issue #28)** —— `wait_task(taskId)` / `wait_any(taskIds)` 一次调用即等到任务到达**停点**(终态或 `needs_user`),专为回合驱动调用方设计:`run_task` 后在本回合内直接等结果,无需自行轮询;纯只读、超时/中断对任务本体零影响。
|
|
62
74
|
- **客观验收,fail-closed** —— 自动命令检查 + 程序化代码分析,全部相对动工前的 **git 基线**,**绝不自动 commit / stash / 回滚**;「测试退出码 0 但零用例」「git 项目零净变更」都判失败,杜绝假绿。
|
|
63
75
|
- **失败返修闭环** —— 自动返修(`autoFixRounds`)+ 手动 `rework_task`;失败原因被解析为**可直接执行的动作**随计划喂回 agent,轮次耗尽转 `needs_attention` 等天枢裁决。
|
|
64
76
|
- **六个 GUI 执行面(CDP)** —— 各 agent 使用隔离的 CDP 流程驱动桌面 UI,并在关键节点上报细粒度事件,`query_task` 因此能区分「agent 正在干活」与「卡在弹窗等人工介入」。
|
|
@@ -114,7 +126,7 @@ Codex · TraeWork · ZCode · Kimi Code · Qoder CN · Open Design
|
|
|
114
126
|
|
|
115
127
|
## 核心特性
|
|
116
128
|
|
|
117
|
-
-
|
|
129
|
+
- **异步派单与等待** —— `run_task` 秒回 `taskId`;`wait_task` 阻塞等到任务到达停点(终态或 `needs_user`),`wait_any` 等一组任务的先到者;需要进度细节时用 `query_task` 看状态 / 进度 / 日志尾 / 最近细粒度事件(`eventLimit`,1..50,默认 10)。详见 [等待原语](docs/wait-task.md)。
|
|
118
130
|
- **客观验收引擎** —— 自动命令检查(typecheck/lint/test/build,缺则跳过 + 技术栈推导)+ 程序化代码分析(变更清单 / diffstat / TODO·debugger·密钥形态等可疑标记),全部相对 **git 基线**;命令默认**有界并行**(`verifyConcurrency`,默认 2,范围 1–4,`1` 即完全串行)。
|
|
119
131
|
- **三项 fail-closed 保护** —— 测试退出码为 0 但零用例判失败;git 项目默认要求相对基线产生变更(纯分析任务可在 `.tianshu-mcp/acceptance.json` 设 `"requireChanges": false` 显式关闭);本轮被取消即 `passed=false`。
|
|
120
132
|
- **验收配置三级继承**(issue #20)—— `<数据目录>/acceptance.default.json`(全局兜底)→ `<项目>/.tianshu-mcp/acceptance.json`(项目覆盖)→ `acceptanceOverride` 参数(任务级临时覆盖,不落盘)。用 `tianshu-mcp config acceptance <projectPath> [--task <id>]` 查看最终生效配置。详见 [验收配置规范](docs/acceptance-config.md)。
|
|
@@ -172,10 +184,10 @@ npm install -g tianshu-mcp
|
|
|
172
184
|
| 命令 | `npx` | `node` |
|
|
173
185
|
| 参数(空格分隔) | `-y tianshu-mcp` | `<仓库绝对路径>/dist/index.js` |
|
|
174
186
|
|
|
175
|
-
> - 服务器 ID 即工具前缀:填 `tianshu-mcp` 后工具名为 `mcp__tianshu-mcp__run_task` 等
|
|
187
|
+
> - 服务器 ID 即工具前缀:填 `tianshu-mcp` 后工具名为 `mcp__tianshu-mcp__run_task` 等 13 个。
|
|
176
188
|
> - 参数按空格分隔填写,**不要加引号**;本地开发模式请把 `<仓库绝对路径>` 换成真实绝对路径。
|
|
177
189
|
> - 界面未提供环境变量输入框;如需自定义数据目录,改用下面的 `config.json` 方式设置 `TIANSHU_MCP_HOME`。
|
|
178
|
-
> - 添加后连接成功即完成;新开会话即可看到
|
|
190
|
+
> - 添加后连接成功即完成;新开会话即可看到 13 个工具。
|
|
179
191
|
|
|
180
192
|
### 或改 config.json(可配环境变量)
|
|
181
193
|
|
|
@@ -193,23 +205,24 @@ npm install -g tianshu-mcp
|
|
|
193
205
|
}
|
|
194
206
|
```
|
|
195
207
|
|
|
196
|
-
新开会话后,工具面出现 `mcp__tianshu-mcp__run_task` 等
|
|
208
|
+
新开会话后,工具面出现 `mcp__tianshu-mcp__run_task` 等 13 个工具。一次典型闭环:
|
|
197
209
|
|
|
198
210
|
```text
|
|
199
211
|
run_task(projectPath=D:/xxx/my-app, task="…任务书…", agentId=codex,
|
|
200
212
|
model="GPT-5.6 Sol", reasoningLevel="高", autoVerify=true, autoFixRounds=5)
|
|
201
|
-
→ taskId →
|
|
213
|
+
→ taskId → wait_task(taskId) 阻塞等到停点 → succeeded / failed / needs_attention → get_task_report 读报告
|
|
214
|
+
(回合驱动调用方:wait_task 一次调用即等到停点;超时返回后再次调用本工具继续等待,或用 query_task 看进度细节)
|
|
202
215
|
```
|
|
203
216
|
|
|
204
217
|
### 给天枢的提示语(推荐用法)
|
|
205
218
|
|
|
206
|
-
> 「在项目 `D:\xxx` 用 codex 实现『任务』。先跑 `run_task(autoVerify:true, autoFixRounds:2)`,完成后用 `
|
|
219
|
+
> 「在项目 `D:\xxx` 用 codex 实现『任务』。先跑 `run_task(autoVerify:true, autoFixRounds:2)`,完成后用 `wait_task` 等到停点再看结果;若报告显示 `needs_attention`,把 `get_task_report` 的失败项摘要作为 `feedback` 调 `rework_task` 再验一轮;全部通过后向我汇报 `changedFiles` 与 `diffstat`。」
|
|
207
220
|
|
|
208
221
|
> 「在项目 `D:\xxx` 用 traework、`mode=Code` 实现『任务』;它会先切到 Code 模式再绑定项目,然后发任务、自动验收,失败自动生成修复计划并返修。」
|
|
209
222
|
|
|
210
223
|
## 工具面
|
|
211
224
|
|
|
212
|
-
|
|
225
|
+
13 个工具,按能力分为三族:`read`(读 / 查询,无副作用)、`write`(有副作用,全部需审批)、`execute`(执行项目侧命令但不改源码,当前仅 `verify_task`,仍免审批)。
|
|
213
226
|
|
|
214
227
|
| 工具 | 能力 / 审批 | 作用 |
|
|
215
228
|
|---|---|---|
|
|
@@ -220,6 +233,8 @@ run_task(projectPath=D:/xxx/my-app, task="…任务书…", agentId=codex,
|
|
|
220
233
|
| `get_task_report` | read | 某轮验收报告全文(`report.md`) |
|
|
221
234
|
| `cancel_task` | write + 审批 | 取消运行中任务:CLI agent kill 进程树;GUI agent 经 CDP 尽力点停止并在 `gui.cancelWaitMs`(默认 15s)内有界等待;对已终态 GUI 任务兼任人工确认入口 |
|
|
222
235
|
| `verify_task` | execute(不改源码,免审批) | 对任务 / 项目路径做一次验收。会跑项目配置命令、可能产生构建产物,故 MCP `readOnlyHint` 为 `false`,但**不改源码、仍免审批**;可选 `idempotencyKey` |
|
|
236
|
+
| `wait_task` | read | 阻塞等待单任务到达停点(终态或 `needs_user`)或超时;`timeoutMs` 缺省 50000、上限 600000,超时返回后再调一次继续等。纯只读、无害 |
|
|
237
|
+
| `wait_any` | read | 阻塞等待一组任务(1..20)中数组顺序首个到达停点者;返回该任务快照 + 全部任务当前状态。校验全部 id 存在,缺一即报错 |
|
|
223
238
|
| `rework_task` | write + 审批 | 手动返修(把失败报告喂回同一 agent);可选 `repairHint`(≤4000 字符) |
|
|
224
239
|
| `get_profiles` | read | 查看 agent 适配与可执行探测结果 |
|
|
225
240
|
| `prepare_visual_baseline` | write + 审批 | 截图或导入参考图,生成待审阅候选和摘要 |
|
|
@@ -236,7 +251,7 @@ run_task(projectPath=D:/xxx/my-app, task="…任务书…", agentId=codex,
|
|
|
236
251
|
| agentId | driver / adapter | status | 说明 |
|
|
237
252
|
|---|---|---|---|
|
|
238
253
|
| `codex` | `gui` / `codex-gui` | **ready**(macOS 为 `research`) | Codex 桌面端 GUI(Windows:MSIX COM 激活 + CDP;macOS:spawn .app + CDP);支持 `model` / `reasoningLevel` / `planDoc` / `designSystem`;等待用户确认、取消与重派护栏均已真机验证 |
|
|
239
|
-
| `zcode` | `gui` / `zcode-gui` | **
|
|
254
|
+
| `zcode` | `gui` / `zcode-gui` | **ready**(Windows 真机闭环;macOS 未验证) | CDP GUI adapter;支持无项目派发、`allowCreateProject` 与 `reasoningLevel`(档位集合**随模型变化**,越权在**发送前**报错);**v0.7.4 适配 3.14.x 的路径契约缺席**(绑定判据改为「路径优先、无路径渠道时按显示名 + 全局同名消歧」,同名即 fail-closed);**v0.7.6 修掉绑定死锁**(侧边栏 `workspace-item-*` 滚出视口仍被采集 → 唯一可信的菜单渠道被短路)、**运行期 CDP 断连的恢复入口**(重连观察一次、绝不重发,失败落 `needs_user(setup_recovery)`)与**两级模型菜单**(provider 分组须 hover 才渲染子项) |
|
|
240
255
|
| `traework` | `gui` / `traework-gui` | **ready** | CDP 驱动 TRAE SOLO CN 桌面 UI;支持 `mode`(Work / Code / Design,三种模式各自维护独立项目绑定);三种面板模式真机验证通过 |
|
|
241
256
|
| `kimicode` | `gui` / `kimicode-gui` | **ready**(macOS 为 `research`) | Kimi Code 桌面端(Electron);**双渲染进程**(主窗口 + `Kimi Browser Overlay` 浮层承载模型 / 档位 / 模式菜单);工作区以完整路径绑定;支持 `model` / `reasoningLevel`,**不支持 `mode`**,且**不支持无项目派发** |
|
|
242
257
|
| `qoder` | `gui` / `qoder-gui` | Windows 真机闭环通过;macOS **research** | 仅 Qoder CN;必须提供已有 `projectPath` 与可读 `planDoc`;`modelSource=default\|custom` 消除同名模型歧义,思考等级经「模型管理」保存为全局偏好并回读 |
|
|
@@ -285,7 +300,7 @@ run_task(projectPath=D:/xxx/my-app, task="…任务书…", agentId=codex,
|
|
|
285
300
|
|
|
286
301
|
| 能力 | 含义 | 审批 | 工具 |
|
|
287
302
|
|---|---|---|---|
|
|
288
|
-
| `read` | 只读 / 查询,无副作用 | 免审批 | `query_task` / `list_tasks` / `get_task_report` / `get_profiles` |
|
|
303
|
+
| `read` | 只读 / 查询,无副作用 | 免审批 | `query_task` / `list_tasks` / `get_task_report` / `get_profiles` / `wait_task` / `wait_any` |
|
|
289
304
|
| `write` | 有副作用 | 需审批 | `run_task` / `continue_task` / `cancel_task` / `rework_task` / 两个视觉基准工具 |
|
|
290
305
|
| `execute` | 执行项目侧命令,不改源码 | 免审批 | `verify_task` |
|
|
291
306
|
|
|
@@ -384,21 +399,15 @@ run_task(projectPath=D:/xxx/my-app, task="…任务书…", agentId=codex,
|
|
|
384
399
|
- **更新日志窗口与双源自动更新** —— 启动静默检查更新,命中即弹「更新日志」(下载并安装 / 忽略此版本 / 稍后),正文即该版本的双语发行说明;更新源由 **Gitee / GitHub 并发实测择优**(不依赖系统区域)决定并如实展示,包体经 **minisign 验签**,**验签不通过一律拒绝安装**。
|
|
385
400
|
|
|
386
401
|
<p align="center">
|
|
387
|
-
<img src="./assets/tianshu-mcp-gui-overview.png" alt="日志台 · 任务概览页" width="
|
|
402
|
+
<a href="./assets/tianshu-mcp-gui-overview.png"><img src="./assets/tianshu-mcp-gui-overview.png" alt="日志台 · 任务概览页" width="32%"></a>
|
|
403
|
+
<a href="./assets/tianshu-mcp-gui-event-stream.png"><img src="./assets/tianshu-mcp-gui-event-stream.png" alt="日志台 · 任务事件流工作区" width="32%"></a>
|
|
404
|
+
<a href="./assets/tianshu-mcp-gui-agent-log.png"><img src="./assets/tianshu-mcp-gui-agent-log.png" alt="日志台 · Agent 原始日志工作区" width="32%"></a>
|
|
388
405
|
<br>
|
|
389
|
-
<
|
|
390
|
-
</p>
|
|
391
|
-
|
|
392
|
-
<p align="center">
|
|
393
|
-
<img src="./assets/tianshu-mcp-gui-event-stream.png" alt="日志台 · 任务事件流工作区" width="88%">
|
|
406
|
+
<b>任务概览页</b> —— 常驻左侧栏 · 五格指标仪(任务总数 / 进行中 / 已结束 / 已成功 / 已失败)· 状态圆片 · 任务卡网格
|
|
394
407
|
<br>
|
|
395
|
-
<
|
|
396
|
-
</p>
|
|
397
|
-
|
|
398
|
-
<p align="center">
|
|
399
|
-
<img src="./assets/tianshu-mcp-gui-agent-log.png" alt="日志台 · Agent 原始日志工作区" width="88%">
|
|
408
|
+
<b>全屏工作区 · 事件流</b> —— 行 / 时间 / 事件 / 详情四列,状态跃迁与进度记录分色标注
|
|
400
409
|
<br>
|
|
401
|
-
<
|
|
410
|
+
<b>全屏工作区 · Agent 日志</b> —— 级别过滤 · 行号与自动换行 · 「已加载 N / 共 M」与「跳到最新」
|
|
402
411
|
</p>
|
|
403
412
|
|
|
404
413
|
解耦与发布边界(改这里之前先读):
|
|
@@ -419,7 +428,8 @@ run_task(projectPath=D:/xxx/my-app, task="…任务书…", agentId=codex,
|
|
|
419
428
|
|
|
420
429
|
| 文档 | 说明 |
|
|
421
430
|
|---|---|
|
|
422
|
-
| [ARCHITECTURE.md](ARCHITECTURE.md) | 架构说明:分层模型与模块边界、状态机、验收流水线、驱动层契约、扩展点与已知缺口 |
|
|
431
|
+
| [ARCHITECTURE.md](<ARCHITECTURE.md>) | 架构说明:分层模型与模块边界、状态机、验收流水线、驱动层契约、扩展点与已知缺口 |
|
|
432
|
+
| [docs/core-principles.md](<docs/core-principles.md>) | 核心原理分析:四条硬约束如何逼出当前架构、核心机制逐条拆解与自洽性总结 |
|
|
423
433
|
| [docs/tianshu-integration.md](docs/tianshu-integration.md) | 天枢 config.json 两种接入模式、UI / API 操作、冒烟步骤、FAQ |
|
|
424
434
|
| [docs/agent-profiles.md](docs/agent-profiles.md) | agent profile 字段说明 + 真实机器样例 |
|
|
425
435
|
| [docs/adapter-matrix.md](docs/adapter-matrix.md) | 各 Agent 能力调研矩阵 |
|
|
@@ -445,7 +455,8 @@ run_task(projectPath=D:/xxx/my-app, task="…任务书…", agentId=codex,
|
|
|
445
455
|
| [docs/repair-directives.md](docs/repair-directives.md) | 结构化修复指令:来源、回退语义与已知限制 |
|
|
446
456
|
| [docs/dry-run.md](docs/dry-run.md) | dryRun 干跑模式:只读约束、零改动门禁、方案文档 |
|
|
447
457
|
| [docs/event-stream.md](docs/event-stream.md) | 细粒度事件流:词表、落盘与读取侧有界窗口 |
|
|
448
|
-
|
|
|
458
|
+
| docs/notifications.md | 任务终态通知:webhook 契约、去重与签名 |
|
|
459
|
+
| docs/wait-task.md | 等待原语:`wait_task` / `wait_any` 契约、停点定义、超时矩阵与循环模式 |
|
|
449
460
|
| [docs/visual-acceptance.md](docs/visual-acceptance.md) | 视觉验收入门与完整配置(含可选 AI 内容校验) |
|
|
450
461
|
| [docs/visual-validation.md](docs/visual-validation.md) | 视觉验收验证进度与平台证据 |
|
|
451
462
|
| [docs/visual-validation-evidence/](docs/visual-validation-evidence/) | 上述验证的原始机器可读记录 |
|