dsh-baton-mcp 0.6.3 → 0.6.4
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/README.md +65 -40
- package/README.zh-CN.md +66 -41
- package/WINDOWS.md +3 -1
- package/host/lib/client.js +3 -38
- package/host/lib/index.js +52 -11
- package/host/package.json +3 -3
- package/package.json +1 -1
- package/server.json +2 -2
- package/src/cli.mjs +7 -6
- package/src/codex-hook.mjs +11 -77
- package/src/core.mjs +35 -6
- package/src/evidence.mjs +38 -5
- package/src/mcp.mjs +66 -37
- package/src/register.mjs +225 -199
- package/src/server.mjs +9 -3
- package/src/setup.mjs +7 -9
package/README.md
CHANGED
|
@@ -1,29 +1,44 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/en/hero-dark.gif"><img src="./assets/readme/en/hero.gif" width="100%" alt="dsh-baton: pass the baton from Claude Code or Codex to DeepSeek Harness, watch it run live, and get it handed back when it's done"></picture>
|
|
3
|
+
</p>
|
|
4
|
+
|
|
1
5
|
<p align="center">
|
|
2
6
|
English | <a href="README.zh-CN.md">中文</a> · macOS · Windows (<a href="WINDOWS.md">guide</a>) · no Node.js needed · zero dependencies · MIT
|
|
3
7
|
</p>
|
|
4
8
|
|
|
5
|
-
#
|
|
9
|
+
<p align="center"><a href="#quick-start">Quick start</a> · <a href="#see-it-run">See it run</a> · <a href="#token-usage">Token usage</a> · <a href="#how-it-works">How it works</a> · <a href="#tools">Tools</a> · <a href="#security-and-limits">Security</a></p>
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
<br>
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
- **Less of the 5-hour window:** on a long Codex job, a ChatGPT Plus 5-hour window goes from 86.01% used to 16.01% with GPT-6 Astra, and from 13.71% to 2.67% with GPT-6.1 Sol.
|
|
11
|
-
- **Nothing to watch or poll:** the agent is woken once when the run ends, and the result already holds the changed files, the test output and the requirement checklist.
|
|
13
|
+
Hand coding tasks from Claude Code or Codex to DeepSeek Harness on your machine: the task runs live in the Harness window, the main agent hears back once when it ends, and it gets back the files that changed, the project's own test results and a requirement-by-requirement checklist.
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
- **Cheaper on money and on quota:** with Claude Code, the total cost, DeepSeek included, is 51–78% lower. On a long Codex job, the share of a ChatGPT Plus 5-hour window it uses goes from 86.01% to 16.01% with GPT-6 Astra, and from 13.71% to 2.67% with GPT-6.1 Sol.
|
|
16
|
+
- **Nothing to watch or poll:** Claude Code is woken once when the run ends; Codex waits out a run of up to an hour in a single call.
|
|
17
|
+
- **A clear split of the work:** Claude Code or Codex writes the request and checks the result; DeepSeek writes the code and runs the tests in Harness. The one who checks is not the one who wrote it.
|
|
14
18
|
|
|
15
|
-
|
|
16
|
-
<img src="./assets/readme/en/hero.gif" width="100%" alt="dsh-baton: pass the baton from Claude Code or Codex to DeepSeek Harness, watch it run live, and get it handed back when it's done">
|
|
17
|
-
</p>
|
|
19
|
+
Needs DeepSeek Harness ≥ 0.2.1-rc.2 (signed in) and Claude Code or Codex. [Quick start →](#quick-start)
|
|
18
20
|
|
|
19
21
|
## What it is
|
|
20
22
|
|
|
21
|
-
dsh-baton is an MCP server plus a small Harness plugin.
|
|
23
|
+
dsh-baton is an MCP server plus a small Harness plugin. The main agent hands the task to an ordinary Harness session with one tool call: you watch it run in the Harness window and can step in at any time, and the main agent hears back once, without polling. Unlike a plain MCP bridge to another model, the work stays visible and the proof comes back with the result.
|
|
24
|
+
|
|
25
|
+
<p align="center"><picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/en/divider-dark.svg"><img src="./assets/readme/en/divider.svg" width="100%" alt=""></picture></p>
|
|
26
|
+
|
|
27
|
+
## Why split the work
|
|
28
|
+
|
|
29
|
+
Beyond the savings, the split itself helps:
|
|
30
|
+
|
|
31
|
+
- **A spec before the code.** The main agent turns your request into concrete items before handing it over, so Harness gets a spec rather than a one-line "build me an X".
|
|
32
|
+
- **Checked on evidence.** The result carries the changed files, your project's own test output and a point-by-point check against the request; anything missing goes back for another round, instead of taking "done" on trust.
|
|
33
|
+
- **The main conversation keeps the decisions.** Hundreds of steps of reading files, editing and running tests stay in the Harness session; the main conversation holds your request and the conclusions.
|
|
34
|
+
- **Visible and steerable.** The work runs live in the Harness window. You can step in there at any time, and the main agent can steer a new requirement into the running turn.
|
|
35
|
+
|
|
36
|
+
<p align="center"><picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/en/divider-dark.svg"><img src="./assets/readme/en/divider.svg" width="100%" alt=""></picture></p>
|
|
22
37
|
|
|
23
38
|
## Quick start
|
|
24
39
|
|
|
25
40
|
<p align="center">
|
|
26
|
-
<img src="./assets/readme/en/install.svg" width="100%" alt="Step 1: in Harness open Plugins, Add plugin, enter dsh-baton-host, Install, Enable now; it registers dsh-baton for Claude Code and Codex. Step 2
|
|
41
|
+
<picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/en/install-dark.svg"><img src="./assets/readme/en/install.svg" width="100%" alt="Step 1: in Harness open Plugins, Add plugin, enter dsh-baton-host, Install, Enable now; it registers dsh-baton for Claude Code and Codex. Step 2: open a new conversation in Claude Code or Codex; Codex asks once to approve the dsh-baton tools. Step 3: ask it to call dsh_list_workspaces; it lists your Harness workspaces."></picture>
|
|
27
42
|
</p>
|
|
28
43
|
|
|
29
44
|
Nothing else to install: no Node.js, no terminal. The steps are the same on macOS and Windows.
|
|
@@ -32,20 +47,15 @@ Nothing else to install: no Node.js, no terminal. The steps are the same on macO
|
|
|
32
47
|
|
|
33
48
|
Switched on, the plugin registers dsh-baton for Claude Code and Codex, for every folder, and Harness says so.
|
|
34
49
|
|
|
35
|
-
**2.
|
|
50
|
+
**2. Open a new chat:** in Claude Code or Codex, start a **new** conversation; one that was already open does not see dsh-baton yet. The steps are the same for both. Codex asks you to approve MCP tool calls: approve the `dsh-baton` tools (for unattended `codex exec` runs, add `--approve-for-me`).
|
|
36
51
|
|
|
37
|
-
|
|
52
|
+
**3. Check:** ask it to call `dsh_list_workspaces`. It lists your Harness workspaces.
|
|
38
53
|
|
|
39
|
-
|
|
40
|
-
<summary>The Codex hook</summary>
|
|
54
|
+
That is all. To hand a task over, end the request with "hand it to DeepSeek Harness". Updating, removing, Windows, and registering by hand when the plugin could not, are [further down](#install-details).
|
|
41
55
|
|
|
42
|
-
|
|
56
|
+
**New in 0.6.4:** Codex waits in one `dsh_wait` call of up to 59 minutes, so a run that ends within the hour costs one model request to wait for, and the result arrives as an ordinary reply in the chat. Update the plugin in Harness and new Codex conversations have it, with no restart.
|
|
43
57
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
**3. Check:** in a **new** Claude Code or Codex conversation, ask it to call `dsh_list_workspaces`. It lists your Harness workspaces. Codex asks you to approve MCP tool calls: approve the `dsh-baton` tools (for unattended `codex exec` runs, add `--approve-for-me`).
|
|
47
|
-
|
|
48
|
-
That is all. If Harness says it could not register, run `npx -y dsh-baton-mcp setup` in a terminal (this needs Node.js ≥ 22.15); it does the same registration. Updating, removing and Windows details are [further down](#install-details).
|
|
58
|
+
<p align="center"><picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/en/divider-dark.svg"><img src="./assets/readme/en/divider.svg" width="100%" alt=""></picture></p>
|
|
49
59
|
|
|
50
60
|
## See it run
|
|
51
61
|
|
|
@@ -54,7 +64,7 @@ That is all. If Harness says it could not register, run `npx -y dsh-baton-mcp se
|
|
|
54
64
|
https://github.com/user-attachments/assets/72e2fdff-275e-48bc-8e5a-39ffb025a0a8
|
|
55
65
|
|
|
56
66
|
<p align="center">
|
|
57
|
-
<img src="./assets/readme/en/flow.gif" width="100%" alt="Typical flow: create a workspace, send the task, wait without polling (Claude Code
|
|
67
|
+
<picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/en/flow-dark.gif"><img src="./assets/readme/en/flow.gif" width="100%" alt="Typical flow: create a workspace, send the task, wait without polling (Claude Code is woken once, Codex waits up to 59 minutes in one dsh_wait call), follow up in the same session"></picture>
|
|
58
68
|
</p>
|
|
59
69
|
|
|
60
70
|
One Codex chat starts a task, queues a follow-up, steers the running turn, and waits for all three:
|
|
@@ -71,10 +81,16 @@ Codex and Claude take turns in the same Harness session, and every message is la
|
|
|
71
81
|
|
|
72
82
|
<p align="center"><a href="docs/demos.md">More demos →</a></p>
|
|
73
83
|
|
|
84
|
+
<p align="center"><picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/en/divider-dark.svg"><img src="./assets/readme/en/divider.svg" width="100%" alt=""></picture></p>
|
|
85
|
+
|
|
74
86
|
## Token usage
|
|
75
87
|
|
|
76
88
|
**In short: hand over the big, long jobs.** With Claude Code the total cost, DeepSeek included, is 51–78% lower. With Codex on GPT-6 Astra it is 47–81% lower, and the long kanban app takes 16.01% of a ChatGPT Plus 5-hour window instead of 86.01%.
|
|
77
89
|
|
|
90
|
+
**Hand it over:** big jobs, long jobs, and whenever the 5-hour window is running low. The main agent's own spend drops 61–87% on every task and model.
|
|
91
|
+
|
|
92
|
+
**Do it yourself:** small tasks on Codex with GPT-6.1 Sol. Sol is cheap enough that DeepSeek's part of a hand-over, two thirds or more, outweighs what Sol saves.
|
|
93
|
+
|
|
78
94
|
**The three test tasks**, asked the way a user would (the requests are in Chinese, linked as written):
|
|
79
95
|
- **Task 1 · CLI tool:** a command-line task manager in Node, no dependencies, split into modules, with tests. [Request](docs/benchmarks/token-usage-2026-10/natural/medium.md)
|
|
80
96
|
- **Task 2 · Web app:** a task manager with a Node server and a page, REST API, stats, tests and a README. [Request](docs/benchmarks/token-usage-2026-10/natural/large.md)
|
|
@@ -108,10 +124,6 @@ Cost per task at list price, DeepSeek V4.1 Flash 1017 at its peak price. Opus 5.
|
|
|
108
124
|
<img src="./docs/benchmarks/token-usage-2026-10/charts/quota.svg" width="100%" alt="Share of a ChatGPT Plus 5-hour window in Codex, working alone vs handed over, grouped by model. GPT-6.1 Sol high: 2.08% vs 0.77%, 5.08% vs 0.79%, 13.71% vs 2.67%. GPT-6 Astra high: 7.83% vs 2.98%, 22.43% vs 2.94%, 86.01% vs 16.01%">
|
|
109
125
|
</p>
|
|
110
126
|
|
|
111
|
-
**Hand it over:** big jobs, long jobs, and whenever the 5-hour window is running low. The main agent's own spend drops 61–87% on every task and model.
|
|
112
|
-
|
|
113
|
-
**Do it yourself:** small tasks on Codex with GPT-6.1 Sol. Sol is cheap enough that DeepSeek's part of a hand-over, two thirds or more, outweighs what Sol saves.
|
|
114
|
-
|
|
115
127
|
<details>
|
|
116
128
|
<summary>What was tested, and how</summary>
|
|
117
129
|
|
|
@@ -120,18 +132,20 @@ Cost per task at list price, DeepSeek V4.1 Flash 1017 at its peak price. Opus 5.
|
|
|
120
132
|
- Tasks 1 and 2: the mean of three runs per cell. Task 3: one run per cell. Every run passed its acceptance check, with no rework.
|
|
121
133
|
- Prices are list prices. DeepSeek is counted at its peak price; the real DeepSeek bill came to about 58% of that.
|
|
122
134
|
- The 5-hour window share is worked out from each run's cost: 12.27 points per $1 for GPT-6.1 Sol, 9.90 for GPT-6 Astra.
|
|
123
|
-
-
|
|
135
|
+
- 0.6.2 cuts the MCP instructions to one sentence, so Codex reads a few thousand to over ten thousand fewer new input tokens per hand-over. The Codex runs were measured with 0.6.1 to 0.6.3, where a Stop hook did the waiting; from 0.6.4 one `dsh_wait` call does it, also in one model request for every 59 minutes of a run.
|
|
124
136
|
|
|
125
137
|
</details>
|
|
126
138
|
|
|
139
|
+
<p align="center"><picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/en/divider-dark.svg"><img src="./assets/readme/en/divider.svg" width="100%" alt=""></picture></p>
|
|
140
|
+
|
|
127
141
|
## How it works
|
|
128
142
|
|
|
129
143
|
<p align="center">
|
|
130
|
-
<img src="./assets/readme/en/architecture.
|
|
144
|
+
<picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/en/architecture-dark.gif"><img src="./assets/readme/en/architecture.gif" width="100%" alt="MCP clients call dsh-baton-mcp over stdio; it reaches the dsh-baton-host plugin inside Harness through an owner-only local socket; the plugin drives Harness sessions live, with dsh headless as fallback"></picture>
|
|
131
145
|
</p>
|
|
132
146
|
|
|
133
147
|
<p align="center">
|
|
134
|
-
<img src="./assets/readme/en/comparison.svg" width="100%" alt="Plugin vs headless: only the plugin shows runs live in the Harness UI, continues desktop sessions and uses desktop agent presets; both reuse the desktop sign-in">
|
|
148
|
+
<picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/en/comparison-dark.svg"><img src="./assets/readme/en/comparison.svg" width="100%" alt="Plugin vs headless: only the plugin shows runs live in the Harness UI, continues desktop sessions and uses desktop agent presets; both reuse the desktop sign-in"></picture>
|
|
135
149
|
</p>
|
|
136
150
|
|
|
137
151
|
**Pick a model:** just say which one, for example "hand it to DeepSeek, V4 Pro". `dsh_send` passes it as `model` (and `reasoning_effort`), matched against the models Harness lists, so a model Harness adds later works as soon as it shows up. It applies to that session only; Harness's default model stays as it was. `dsh_list_models` shows what is available.
|
|
@@ -142,8 +156,8 @@ Nothing to configure for waiting; if you want to know what each client does whil
|
|
|
142
156
|
<summary>How each client waits</summary>
|
|
143
157
|
|
|
144
158
|
- **Claude Code** waits for a run in the background (the `wait_command` that `dsh_send` returns) and is woken once, when the run ends.
|
|
145
|
-
- **Codex**
|
|
146
|
-
- **Codex**
|
|
159
|
+
- **Codex** waits inside `dsh_wait`. The plugin sets Codex's tool timeout for dsh-baton to an hour (`tool_timeout_sec = 3600`), so one call waits up to 59 minutes: a run that ends within the hour costs one model request to wait for, however long it takes, and the result comes back as an ordinary tool result in the chat. A longer run returns `timed_out` with just the state after 59 minutes, and Codex calls again without summarising. Pressing Stop ends the wait at once. Codex gets no `wait_command`: its terminal cannot wake it, so it would poll. Conversations opened before the plugin set the timeout, or an entry you wrote yourself without it, wait 270 s per call, just under Codex's default 300 s timeout. Measured in the Codex desktop app: a 28-minute run took one `dsh_wait` call; a 62-minute run took two, the first returning `timed_out` after 59 minutes and the second getting the result 3 minutes later, with no `dsh_status` calls in between.
|
|
160
|
+
- **Changing the request while it waits.** In Codex, send the change with **Steer**: Codex stops waiting at once, steers it into the same Harness session (`dsh_send` with `mode` `steer`) and waits on the new run; Harness does both in the same turn. Sent with **Queue**, Codex sees it only when the run ends; you can also press Stop first and then send it. In Claude Code, just send it: it waits in the background, so it steers the change in right away. A steered run ends together with the original and they share one result; a queued run comes back on its own. Runs working in the same folder at the same time are named in each other's results, so neither removes the other's files.
|
|
147
161
|
|
|
148
162
|
</details>
|
|
149
163
|
|
|
@@ -155,14 +169,16 @@ You don't have to take DeepSeek's word for it. Before the run, dsh-baton notes w
|
|
|
155
169
|
<img src="./docs/benchmarks/token-usage-2026-10/charts/evidence-chain.svg" width="100%" alt="Evidence chain of one real hand-over: the user asks, Codex writes the spec and checks, dsh-baton snapshots the folder, DeepSeek Harness writes 11 files, dsh-baton lists the changed files and runs npm test itself, Codex sends one fix back on its own, dsh-baton checks again, Codex accepts, and the benchmark's own test passes 13 of 13">
|
|
156
170
|
</p>
|
|
157
171
|
|
|
172
|
+
<p align="center"><picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/en/divider-dark.svg"><img src="./assets/readme/en/divider.svg" width="100%" alt=""></picture></p>
|
|
173
|
+
|
|
158
174
|
## Tools
|
|
159
175
|
|
|
160
176
|
<p align="center">
|
|
161
|
-
<img src="./assets/readme/en/tools.svg" width="100%" alt="Ten tools in the tool list: list workspaces, list sessions, read session, list models, send, status, wait, answer, cancel, call. Six less used tools are reached through dsh_call: create and rename workspace, session activity, rename session, update queued, list runs">
|
|
177
|
+
<picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/en/tools-dark.svg"><img src="./assets/readme/en/tools.svg" width="100%" alt="Ten tools in the tool list: list workspaces, list sessions, read session, list models, send, status, wait, answer, cancel, call. Six less used tools are reached through dsh_call: create and rename workspace, session activity, rename session, update queued, list runs"></picture>
|
|
162
178
|
</p>
|
|
163
179
|
|
|
164
180
|
<p align="center">
|
|
165
|
-
<img src="./assets/readme/en/states.
|
|
181
|
+
<picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/en/states-dark.gif"><img src="./assets/readme/en/states.gif" width="100%" alt="Run states: queued, running, waiting, completed, failed, cancelled, and interrupted when Harness restarts mid-run. A busy session takes followup (queued) or steer (interjects) messages; left unset, your Harness setting decides"></picture>
|
|
166
182
|
</p>
|
|
167
183
|
|
|
168
184
|
When you want the exact parameters and return fields of each tool:
|
|
@@ -181,7 +197,7 @@ The server's MCP instructions are a single sentence (from 0.6.2); how to hand ov
|
|
|
181
197
|
| `dsh_read_session` | Recent prompts and replies of one session (with tool names); `archived: true` for an archived session |
|
|
182
198
|
| `dsh_send` | Send a message: `session_id` continues that session; otherwise a new one starts in `cwd` or `workspace_id`, or, with neither, in the folder the conversation works in (a `cwd` that is not a workspace yet is registered first; a `cwd` outside the conversation's folder is allowed and noted in `folder_note`). `checks`: test commands dsh-baton runs itself when the run ends (see [How a hand-over is checked](#how-a-hand-over-is-checked)). Returns a `run_id` at once. In Harness the message is marked "Sent by Claude / ChatGPT from another chat". An archived session is refused: unarchive it in Harness, or start a new session. To a busy session, `mode` `followup` queues the message after the current turn and `steer` adds it to the running turn; left out, it does what Harness's own setting says (Settings → sending while busy: queue or steer), and `followup` when that cannot be read. `mode_source` says which applied. `model` only when the user names one ("DeepSeek-V4 Pro", "v4-pro"; `reasoning_effort` likewise): it is matched against Harness's own model list, ignoring case, spaces, hyphens and a leading DeepSeek, so a model Harness adds later (V4.1 Pro) works as soon as Harness lists it; a name that matches nothing or several fails the send, before anything is created, with the list (`provider/model` picks one). It is set on that session before the message goes in, and Harness's default model is put back as it was (Harness saves a session's pick as the default too). Left out, a continued session keeps its own model and a new one uses Harness's default. The reply says which in `model` and `model_source` |
|
|
183
199
|
| `dsh_status` | Run progress: state, recent text and tool calls, final reply; `waiting_on` when the turn is over but sub-agents or jobs still run; `human_interjections` when someone typed in the Harness UI mid-run; state `interrupted` for a run cut short by a Harness restart; `model` the run was sent with |
|
|
184
|
-
| `dsh_wait` |
|
|
200
|
+
| `dsh_wait` | Wait for the run to end; a finished run carries `evidence` (files changed, check results) when the message was sent with `checks` (or until it stops to ask a person, see `dsh_answer`): up to 3540 s per call for Codex (its tool timeout for dsh-baton less 60 s; 270 s when that is not set), 50 s for other clients. Still going: returns `timed_out` with just the state; call it again. Clients that can wait in the background use `dsh_send`'s `wait_command` instead. `dsh_status` is a one-off look, not a way to wait |
|
|
185
201
|
| `dsh_answer` | Answer the questions a run stopped to ask (Harness's ask_user_question): per question, an option number or label, free text, or skip; one at a time or all at once. `dsh_wait` and `wait_command` return as soon as a run asks, with the questions (`needs_input`, `question`; the option Harness's model would pick is in `harness_suggested`, apart from the labels). The assistant answers by its own judgment only when you told it to decide, and then passes `reason` and tells you what it chose and why; otherwise it brings you the questions, starting with its own recommendation and reason. You can also answer in the Harness window: whoever answers first wins |
|
|
186
202
|
| `dsh_session_activity` | Through `dsh_call`. What a session is doing now: running turn, sub-agents (any depth), background jobs; `archived: true` for an archived session |
|
|
187
203
|
| `dsh_update_queued` | Through `dsh_call`. Change a message still waiting in the queue of a busy session, by its `run_id`: `edit` its text, `remove` it, or `steer` it into the running turn now. Once it has reached the conversation it can no longer be changed |
|
|
@@ -193,6 +209,8 @@ The server's MCP instructions are a single sentence (from 0.6.2); how to hand ov
|
|
|
193
209
|
|
|
194
210
|
</details>
|
|
195
211
|
|
|
212
|
+
<p align="center"><picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/en/divider-dark.svg"><img src="./assets/readme/en/divider.svg" width="100%" alt=""></picture></p>
|
|
213
|
+
|
|
196
214
|
## Command line and configuration
|
|
197
215
|
|
|
198
216
|
When you want to drive Harness from a terminal or a script instead of a chat:
|
|
@@ -229,8 +247,7 @@ When the defaults don't fit, for example a different socket path or forcing head
|
|
|
229
247
|
| `DSH_BATON_BACKEND` | `auto` | `auto`, `host` or `headless` |
|
|
230
248
|
| `DSH_BATON_HOME` | `~/.dsh-baton` | Socket and headless run records |
|
|
231
249
|
| `DSH_BATON_SOCKET` | `$DSH_BATON_HOME/host.sock` | Plugin socket path (must match on both sides); on Windows mapped to a per-user named pipe, see [WINDOWS.md](WINDOWS.md) |
|
|
232
|
-
| `DSH_BATON_WAIT_S` | `
|
|
233
|
-
| `DSH_BATON_CODEX_HOOK` | `1` | `0` (set for Harness) stops the plugin adding the Codex Stop hook |
|
|
250
|
+
| `DSH_BATON_WAIT_S` | Codex: its `tool_timeout_sec` for dsh-baton less 60 (3540 as the plugin sets it, else 270); others `50` | How long one `dsh_wait` call waits; keep it below the client's tool timeout |
|
|
234
251
|
| `DSH_BIN` | the `dsh` inside the macOS app, else `PATH` | Harness CLI for headless mode |
|
|
235
252
|
| `DSH_HOME` | `~/.dsh` | Harness data folder (headless session reads) |
|
|
236
253
|
| `DSH_BATON_ACCOUNT` | `1` | `0` uses the API-key route in headless mode |
|
|
@@ -247,6 +264,8 @@ When the plugin is unreachable, the MCP server falls back to Harness's `dsh head
|
|
|
247
264
|
|
|
248
265
|
</details>
|
|
249
266
|
|
|
267
|
+
<p align="center"><picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/en/divider-dark.svg"><img src="./assets/readme/en/divider.svg" width="100%" alt=""></picture></p>
|
|
268
|
+
|
|
250
269
|
## Install details
|
|
251
270
|
|
|
252
271
|
When you update or remove the plugin, come from dsh-bridge, run from source, or the plugin could not register:
|
|
@@ -256,13 +275,15 @@ When you update or remove the plugin, come from dsh-bridge, run from source, or
|
|
|
256
275
|
|
|
257
276
|
**What the plugin does when switched on.** It copies the MCP server to `~/.dsh-baton/app`, a folder that stays put, and writes the MCP entry into `~/.claude.json` and `~/.codex/config.toml` directly, keeping a `*.bak-dsh-baton` backup of each. It starts the server with your own Node.js ≥ 22.15 when it finds one on `PATH`; without one, with Harness's own runtime (the Harness app in Node mode, `ELECTRON_RUN_AS_NODE=1`), so nothing else has to be installed. Either way it works with only the desktop apps installed, when `claude` / `codex` are not on your `PATH`. It runs again on each Harness start: an entry that is already right, or a working one that starts another copy of dsh-baton, is left alone. In Harness, the source switches to the npm registry ("Official npm registry", 「npm 官方源」) by itself once you type the package name, and no restart is needed. To turn the registration off, set `DSH_BATON_AUTO_REGISTER=0` for Harness.
|
|
258
277
|
|
|
259
|
-
**
|
|
278
|
+
**Codex's tool timeout.** Codex stops an MCP tool call after 300 s unless the server's table sets `tool_timeout_sec`. The plugin writes `tool_timeout_sec = 3600` into `[mcp_servers.dsh-baton]` in `~/.codex/config.toml`, and adds it to an existing table that has none; a value you set yourself is kept. The server reads it and makes each `dsh_wait` that long less 60 s. Codex reads the setting when a conversation starts and keeps it: new conversations get it without restarting Codex, while conversations already open keep Codex's 300 s limit, so dsh-baton, which tells them apart by when they started (`~/.dsh-baton/codex-timeout.json` holds when the value was written), keeps their waits at 270 s.
|
|
279
|
+
|
|
280
|
+
**Updating to 0.6.4.** Nothing to restart, approve or set. Updating the plugin in Harness installs the new server into `~/.dsh-baton/app` and writes the timeout; Codex's running server picks up the new version on its next call (it checks for a newer copy before each `tools/list` and `tools/call`). New conversations wait up to 59 minutes per call; conversations already open go on as before, with 270 s waits. The Stop hook that plugins 0.6.0 to 0.6.3 added is taken out by itself, together with its trust record; there is nothing to untick in Codex. New conversations, and every conversation after Codex restarts, have no hook at all.
|
|
260
281
|
|
|
261
282
|
**Updates need no restart.** When a newer version lands in `~/.dsh-baton/app` (a plugin update, `setup`, or a copy by hand), or the same version with changed files, conversations already open in Claude Code and Codex use it from their next `dsh_*` call: the server checks the folder before each call, starts the new version, and says once in that call's result that it was updated. A `dsh_wait` that is already running finishes on the old version first. If the new version cannot start, the old one keeps working and the result says why. A tool added in the new version shows up in Claude Code at once (the server tells the client its tool list changed); Codex keeps the tool list a conversation started with, so it does not show a new tool until the next conversation; it can still use one at once through `dsh_call`, which the update note points to, and the tools it already has run the new code right away.
|
|
262
283
|
|
|
263
284
|
**`npx -y dsh-baton-mcp setup`** does the same registration from a terminal: for a plugin that could not register, or when you come from an MCP directory. With the plugin already registered it changes nothing, then points you to the plugin if it is missing.
|
|
264
285
|
|
|
265
|
-
**Updating.** Harness has an update button only for its official plugins, so: Plugins → dsh-baton-host → **Uninstall**, then **Add plugin** → `dsh-baton-host`. For a while after a release, Harness installs the previous version instead (pnpm's `minimumReleaseAge` holds back versions published very recently, and the install dialog says so); to get the new one at once, type the version: `dsh-baton-host@0.6.
|
|
286
|
+
**Updating.** Harness has an update button only for its official plugins, so: Plugins → dsh-baton-host → **Uninstall**, then **Add plugin** → `dsh-baton-host`. For a while after a release, Harness installs the previous version instead (pnpm's `minimumReleaseAge` holds back versions published very recently, and the install dialog says so); to get the new one at once, type the version: `dsh-baton-host@0.6.4`. A pre-release must always be added by its exact version, such as `dsh-baton-host@0.6.0-next.0`: Harness resolves `@next` to a broken placeholder. Plain `dsh-baton-host` gets the latest release. Switched on again, the plugin brings the MCP server to the same version; new conversations use it. If the two are ever out of step, the first tool call that notices it says so, naming the older side and the newer side's exact version to install.
|
|
266
287
|
|
|
267
288
|
**Removing.** Harness → Plugins → dsh-baton-host → **Uninstall**, then `npx -y dsh-baton-mcp setup --remove`. The plugin cannot tell an uninstall from Harness quitting, so it leaves the MCP entries to that command, which also deletes `~/.dsh-baton/app`; run records stay in `~/.dsh-baton` until you delete it.
|
|
268
289
|
|
|
@@ -296,18 +317,22 @@ codex mcp add dsh-baton -- "$(command -v node)" "$PWD/dsh-baton/src/server.mjs"
|
|
|
296
317
|
|
|
297
318
|
</details>
|
|
298
319
|
|
|
320
|
+
<p align="center"><picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/en/divider-dark.svg"><img src="./assets/readme/en/divider.svg" width="100%" alt=""></picture></p>
|
|
321
|
+
|
|
299
322
|
## Security and limits
|
|
300
323
|
|
|
301
324
|
<p align="center">
|
|
302
|
-
<img src="./assets/readme/en/security.svg" width="100%" alt="Owner-only channel (socket 0600 on macOS and Linux, per-user named pipe on Windows), no network port, Harness sandbox and approvals apply">
|
|
325
|
+
<picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/en/security-dark.svg"><img src="./assets/readme/en/security.svg" width="100%" alt="Owner-only channel (socket 0600 on macOS and Linux, per-user named pipe on Windows), no network port, Harness sandbox and approvals apply"></picture>
|
|
303
326
|
</p>
|
|
304
327
|
|
|
305
328
|
<p align="center">
|
|
306
|
-
<img src="./assets/readme/en/limits.svg" width="100%" alt="Good to know: a message typed in the UI mid-run is flagged on the run as a human interjection, run records survive a Harness restart (cut-short runs show interrupted), Claude Code
|
|
329
|
+
<picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/en/limits-dark.svg"><img src="./assets/readme/en/limits.svg" width="100%" alt="Good to know: a message typed in the UI mid-run is flagged on the run as a human interjection, run records survive a Harness restart (cut-short runs show interrupted), Claude Code is woken once when a run ends, Codex waits up to 59 minutes in one call"></picture>
|
|
307
330
|
</p>
|
|
308
331
|
|
|
309
332
|
Any process running as your OS user can drive Harness through the socket, the same as running `dsh` directly. dsh-baton relies on Harness 0.2.1-series internal service APIs, so a major Harness update may need a follow-up release.
|
|
310
333
|
|
|
334
|
+
<p align="center"><picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/en/divider-dark.svg"><img src="./assets/readme/en/divider.svg" width="100%" alt=""></picture></p>
|
|
335
|
+
|
|
311
336
|
## License
|
|
312
337
|
|
|
313
338
|
MIT
|
package/README.zh-CN.md
CHANGED
|
@@ -1,51 +1,61 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/zh/hero-dark.gif"><img src="./assets/readme/zh/hero.gif" width="100%" alt="dsh-baton:让 Claude Code 或 Codex 把接力棒交给 DeepSeek Harness,界面实时可见,跑完那一刻就交回给你"></picture>
|
|
3
|
+
</p>
|
|
4
|
+
|
|
1
5
|
<p align="center">
|
|
2
6
|
<a href="README.md">English</a> | 中文 · macOS · Windows(<a href="WINDOWS.md">说明</a>)· 不用装 Node.js · 零依赖 · MIT
|
|
3
7
|
</p>
|
|
4
8
|
|
|
5
|
-
#
|
|
9
|
+
<p align="center"><a href="#快速上手">快速上手</a> · <a href="#看它跑">看它跑</a> · <a href="#token-用量实测">Token 用量</a> · <a href="#工作原理">工作原理</a> · <a href="#工具">工具</a> · <a href="#安全与限制">安全</a></p>
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
<br>
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
- **少用 5 小时额度**:Codex 长任务,ChatGPT Plus 5 小时额度用 GPT-6 Astra 从 86.01% 降到 16.01%,用 GPT-6.1 Sol 从 13.71% 降到 2.67%。
|
|
11
|
-
- **不用盯、不用轮询**:跑完只唤醒一次,结果自带改动文件、测试输出和需求对照。
|
|
13
|
+
把 Claude Code 或 Codex 的编码任务交给本机的 DeepSeek Harness:任务在 Harness 界面里实时跑,跑完主 Agent 收到一次结果,带回改了哪些文件、项目自己的测试结果,以及逐条需求对照表。
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
- **省钱也省额度**:Claude Code 连 DeepSeek 一起算,总花费少 51–78%。Codex 长任务占 ChatGPT Plus 5 小时额度的比例,用 GPT-6 Astra 从 86.01% 降到 16.01%,用 GPT-6.1 Sol 从 13.71% 降到 2.67%。
|
|
16
|
+
- **不用盯、不用轮询**:Claude Code 跑完只被唤醒一次,Codex 一次调用就能等完一小时以内的任务。
|
|
17
|
+
- **分工明确**:Claude Code 或 Codex 定需求、做验收,DeepSeek 在 Harness 里写代码、跑测试。验收的一方不是写代码的一方。
|
|
14
18
|
|
|
15
|
-
|
|
16
|
-
<img src="./assets/readme/zh/hero.gif" width="100%" alt="dsh-baton:让 Claude Code 或 Codex 把接力棒交给 DeepSeek Harness,界面实时可见,跑完那一刻就交回给你">
|
|
17
|
-
</p>
|
|
19
|
+
需要 DeepSeek Harness ≥ 0.2.1-rc.2(已登录)和 Claude Code 或 Codex。[快速上手 →](#快速上手)
|
|
18
20
|
|
|
19
21
|
## 这是什么
|
|
20
22
|
|
|
21
|
-
dsh-baton 是一个 MCP 服务器加一个 Harness 小插件。主 Agent
|
|
23
|
+
dsh-baton 是一个 MCP 服务器加一个 Harness 小插件。主 Agent 用一次工具调用把任务交给一个普通的 Harness 对话:你在界面里看着它跑,随时能插话;跑完主 Agent 只收到一次结果,不用轮询。和普通的 MCP 桥接另一个模型相比,过程看得见,证据随结果一起带回来。
|
|
24
|
+
|
|
25
|
+
<p align="center"><picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/zh/divider-dark.svg"><img src="./assets/readme/zh/divider.svg" width="100%" alt=""></picture></p>
|
|
26
|
+
|
|
27
|
+
## 为什么要分工
|
|
28
|
+
|
|
29
|
+
省钱之外,分工本身也有好处:
|
|
30
|
+
|
|
31
|
+
- **先写规格,再动手**。主 Agent 先把你的需求拆成明确的条目再交出去,Harness 拿到的是一份规格,而不是一句“帮我做个 X”。
|
|
32
|
+
- **验收看证据**。结果带回改动文件、项目自己的测试输出和逐条需求对照;没做到的条目再发回去改,不靠一句“做完了”。
|
|
33
|
+
- **主对话只留决策**。几百步的读文件、改代码、跑测试都留在 Harness 对话里,主对话里只有你的需求和结论。
|
|
34
|
+
- **看得见、能插话**。执行过程在 Harness 界面里实时显示,你随时可以在那里插话;主 Agent 也能把新要求插进正在跑的回合。
|
|
35
|
+
|
|
36
|
+
<p align="center"><picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/zh/divider-dark.svg"><img src="./assets/readme/zh/divider.svg" width="100%" alt=""></picture></p>
|
|
22
37
|
|
|
23
38
|
## 快速上手
|
|
24
39
|
|
|
25
40
|
<p align="center">
|
|
26
|
-
<img src="./assets/readme/zh/install.svg" width="100%" alt="第一步:Harness → 插件 → 添加插件 → 输入 dsh-baton-host → 安装 → 立即启用,它会为 Claude Code 和 Codex 注册 dsh-baton
|
|
41
|
+
<picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/zh/install-dark.svg"><img src="./assets/readme/zh/install.svg" width="100%" alt="第一步:Harness → 插件 → 添加插件 → 输入 dsh-baton-host → 安装 → 立即启用,它会为 Claude Code 和 Codex 注册 dsh-baton。第二步:在 Claude Code 或 Codex 里新开一个对话;Codex 第一次会请你批准 dsh-baton 的工具。第三步:让它调用 dsh_list_workspaces,会列出你的 Harness 工作区。"></picture>
|
|
27
42
|
</p>
|
|
28
43
|
|
|
29
44
|
别的都不用装:不用 Node.js,也不用开终端。macOS 和 Windows 步骤完全相同。
|
|
30
45
|
|
|
31
|
-
**1. 在 Harness 里添加插件:**
|
|
46
|
+
**1. 在 Harness 里添加插件:** **插件** → **添加插件** → 输入 `dsh-baton-host` → **安装** → **立即启用**。
|
|
32
47
|
|
|
33
48
|
插件启用后会为 Claude Code 和 Codex 注册 dsh-baton(对所有文件夹生效),Harness 里会弹出提示。
|
|
34
49
|
|
|
35
|
-
**2.
|
|
50
|
+
**2. 新开对话**:在 Claude Code 或 Codex 里**新开**一个对话,之前开着的对话还看不到 dsh-baton。两边步骤一样。Codex 调用 MCP 工具时会请你批准,批准 `dsh-baton` 的工具即可(无人值守的 `codex exec` 加上 `--approve-for-me`)。
|
|
36
51
|
|
|
37
|
-
|
|
52
|
+
**3. 检查**:让它调用 `dsh_list_workspaces`,会列出你的 Harness 工作区。
|
|
38
53
|
|
|
39
|
-
|
|
40
|
-
<summary>Codex 钩子</summary>
|
|
54
|
+
就这些。要转交任务,在需求最后加一句“交给 DeepSeek Harness 去做”。更新、卸载、Windows,以及插件没能注册时怎么手动注册,在[后面](#安装细节)。
|
|
41
55
|
|
|
42
|
-
|
|
56
|
+
**0.6.4 新变化**:Codex 一次 `dsh_wait` 最多等 59 分钟,一小时以内跑完的任务等待只花一次模型请求,结果作为普通回复回到对话里。在 Harness 里更新插件,新开的 Codex 对话就用上了,不用重启。
|
|
43
57
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
**3. 检查**:在 Claude Code 或 Codex 里**新开**一个对话,让它调用 `dsh_list_workspaces`,会列出你的 Harness 工作区。Codex 调用 MCP 工具时会请你批准,批准 `dsh-baton` 的工具即可(无人值守的 `codex exec` 加上 `--approve-for-me`)。
|
|
47
|
-
|
|
48
|
-
就这些。如果 Harness 提示没能注册,在终端运行 `npx -y dsh-baton-mcp setup`(这需要 Node.js ≥ 22.15),它做的是同样的注册。更新、卸载和 Windows 说明在[后面](#安装细节)。
|
|
58
|
+
<p align="center"><picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/zh/divider-dark.svg"><img src="./assets/readme/zh/divider.svg" width="100%" alt=""></picture></p>
|
|
49
59
|
|
|
50
60
|
## 看它跑
|
|
51
61
|
|
|
@@ -54,7 +64,7 @@ dsh-baton 是一个 MCP 服务器加一个 Harness 小插件。主 Agent(Claud
|
|
|
54
64
|
https://github.com/user-attachments/assets/ed931637-acb3-4c16-8c52-72298ea90485
|
|
55
65
|
|
|
56
66
|
<p align="center">
|
|
57
|
-
<img src="./assets/readme/zh/flow.gif" width="100%" alt="典型流程:新建工作区、派发任务、不轮询地等待(Claude Code
|
|
67
|
+
<picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/zh/flow-dark.gif"><img src="./assets/readme/zh/flow.gif" width="100%" alt="典型流程:新建工作区、派发任务、不轮询地等待(Claude Code 结束时被唤醒一次,Codex 一次 dsh_wait 最多等 59 分钟)、在同一个对话里续接追问"></picture>
|
|
58
68
|
</p>
|
|
59
69
|
|
|
60
70
|
一个 Codex 对话里完成新建、排队、插队和等待:
|
|
@@ -71,10 +81,16 @@ Codex 和 Claude 轮流往同一个 Harness 对话发消息,每条都标明是
|
|
|
71
81
|
|
|
72
82
|
<p align="center"><a href="docs/demos.zh-CN.md">更多演示 →</a></p>
|
|
73
83
|
|
|
84
|
+
<p align="center"><picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/zh/divider-dark.svg"><img src="./assets/readme/zh/divider.svg" width="100%" alt=""></picture></p>
|
|
85
|
+
|
|
74
86
|
## Token 用量实测
|
|
75
87
|
|
|
76
88
|
**一句话:大活、长活交给它**。Claude Code 连 DeepSeek 一起算,总花费少 51–78%;Codex 用 GPT-6 Astra 少 47–81%,分阶段的看板应用占 ChatGPT Plus 5 小时额度从 86.01% 降到 16.01%。
|
|
77
89
|
|
|
90
|
+
**适合转交**:大任务、长任务,以及 5 小时额度快用完的时候。每个案例、每个模型,主 Agent 自己的花费都少了 61–87%。
|
|
91
|
+
|
|
92
|
+
**适合自己做**:Codex 用 GPT-6.1 Sol 的小任务。Sol 本身够便宜,转交时 DeepSeek 那部分要占到三分之二以上,抵掉了 Sol 省下的钱。
|
|
93
|
+
|
|
78
94
|
**三个测试案例**,都按普通用户的口吻提需求(原文可以直接点开看):
|
|
79
95
|
- **案例 1 · 命令行工具**:用 Node 写一个命令行任务管理工具,零依赖,分模块,带测试。[需求原文](docs/benchmarks/token-usage-2026-10/natural/medium.md)
|
|
80
96
|
- **案例 2 · 任务管理网页**:Node 服务器加前端页面,REST 接口、统计、测试和 README。[需求原文](docs/benchmarks/token-usage-2026-10/natural/large.md)
|
|
@@ -108,10 +124,6 @@ Codex 和 Claude 轮流往同一个 Harness 对话发消息,每条都标明是
|
|
|
108
124
|
<img src="./docs/benchmarks/token-usage-2026-10/charts/quota.zh.svg" width="100%" alt="Codex 占 ChatGPT Plus 5 小时额度,自己做对转交,按模型分组。GPT-6.1 Sol high:2.08% 对 0.77%,5.08% 对 0.79%,13.71% 对 2.67%。GPT-6 Astra high:7.83% 对 2.98%,22.43% 对 2.94%,86.01% 对 16.01%">
|
|
109
125
|
</p>
|
|
110
126
|
|
|
111
|
-
**适合转交**:大任务、长任务,以及 5 小时额度快用完的时候。每个案例、每个模型,主 Agent 自己的花费都少了 61–87%。
|
|
112
|
-
|
|
113
|
-
**适合自己做**:Codex 用 GPT-6.1 Sol 的小任务。Sol 本身够便宜,转交时 DeepSeek 那部分要占到三分之二以上,抵掉了 Sol 省下的钱。
|
|
114
|
-
|
|
115
127
|
<details>
|
|
116
128
|
<summary>测了什么、怎么测的</summary>
|
|
117
129
|
|
|
@@ -120,18 +132,20 @@ Codex 和 Claude 轮流往同一个 Harness 对话发消息,每条都标明是
|
|
|
120
132
|
- 案例 1、2:每格 3 次取平均。案例 3:每格 1 次。全部通过验收,没有返工。
|
|
121
133
|
- 价格按标价算。DeepSeek 按高峰价;实际 DeepSeek 账单大约是这个数的 58%。
|
|
122
134
|
- 5 小时额度按每次运行的花费换算:GPT-6.1 Sol 每 $1 合 12.27 个百分点,GPT-6 Astra 合 9.90 个。
|
|
123
|
-
- 0.6.
|
|
135
|
+
- 0.6.2 把 MCP 说明缩成一句话,Codex 每次转交少读几千到一万多个新输入 token。Codex 的数据是在 0.6.1 到 0.6.3 上测的,那时由 Stop 钩子负责等待;0.6.4 起改由一次 `dsh_wait` 等待,同样是任务每跑 59 分钟只花一次模型请求。
|
|
124
136
|
|
|
125
137
|
</details>
|
|
126
138
|
|
|
139
|
+
<p align="center"><picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/zh/divider-dark.svg"><img src="./assets/readme/zh/divider.svg" width="100%" alt=""></picture></p>
|
|
140
|
+
|
|
127
141
|
## 工作原理
|
|
128
142
|
|
|
129
143
|
<p align="center">
|
|
130
|
-
<img src="./assets/readme/zh/architecture.
|
|
144
|
+
<picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/zh/architecture-dark.gif"><img src="./assets/readme/zh/architecture.gif" width="100%" alt="MCP 客户端通过 stdio 调用 dsh-baton-mcp,再经仅当前用户可访问的本地套接字连到 Harness 里的 dsh-baton-host 插件,插件驱动 Harness 的对话并实时显示;插件不可用时退回 dsh headless"></picture>
|
|
131
145
|
</p>
|
|
132
146
|
|
|
133
147
|
<p align="center">
|
|
134
|
-
<img src="./assets/readme/zh/comparison.svg" width="100%" alt="插件和 headless 对比:只有插件能在 Harness 界面实时可见、续接桌面版的对话、使用桌面版智能体预设;两者都沿用桌面版登录">
|
|
148
|
+
<picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/zh/comparison-dark.svg"><img src="./assets/readme/zh/comparison.svg" width="100%" alt="插件和 headless 对比:只有插件能在 Harness 界面实时可见、续接桌面版的对话、使用桌面版智能体预设;两者都沿用桌面版登录"></picture>
|
|
135
149
|
</p>
|
|
136
150
|
|
|
137
151
|
**指定模型**:直接说用哪个就行,比如「交给 DeepSeek,用 V4 Pro」。`dsh_send` 会把它作为 `model`(以及 `reasoning_effort`)传过去,按 Harness 自己的模型列表匹配,所以 Harness 以后新加的模型一出现就能用。只对这个对话生效,Harness 的默认模型保持不变。`dsh_list_models` 可以看有哪些模型。
|
|
@@ -142,8 +156,8 @@ Codex 和 Claude 轮流往同一个 Harness 对话发消息,每条都标明是
|
|
|
142
156
|
<summary>各客户端怎么等待</summary>
|
|
143
157
|
|
|
144
158
|
- **Claude Code** 在后台等待任务(`dsh_send` 返回的 `wait_command`),任务结束时只被唤醒一次。
|
|
145
|
-
- **Codex
|
|
146
|
-
-
|
|
159
|
+
- **Codex** 在 `dsh_wait` 里等待。插件把 Codex 对 dsh-baton 的工具超时设为一小时(`tool_timeout_sec = 3600`),所以一次调用最多能等 59 分钟:一小时以内跑完的任务,不管跑多久,等待只花一次模型请求,结果作为普通的工具结果回到对话里。超过 59 分钟会返回 `timed_out`,只带状态,Codex 直接再调用一次,不会去总结进度。等待中按停止会立刻停下。Codex 不会收到 `wait_command`:它的终端无法在命令结束时唤醒它,只能轮询。插件设好超时之前就开着的对话,或者你自己写的、没有这项设置的条目,每次最多等 270 秒,刚好低于 Codex 默认 300 秒的工具超时。实测(Codex 桌面端):28 分钟的任务只调了 1 次 `dsh_wait`;62 分钟的任务调了 2 次,第一次等满 59 分钟返回 `timed_out`,接着再等 3 分钟拿到结果;期间没有调用 `dsh_status`。
|
|
160
|
+
- **等待中想改需求**。Codex:在输入框里用**引导**发出新要求,Codex 会立刻停止等待,用 `dsh_send`(`mode` 为 `steer`)把它插进同一个 Harness 对话,改等新的任务,Harness 在同一轮里把新要求一起做完;用**排队**发的话,要等这次任务做完才会被看到。也可以先按停止再发。Claude Code:随时发就行,它在后台等待,马上就能把新要求插队转给 Harness。插队的任务和原任务同时结束,共用一份结果;排队的任务单独返回。同一个文件夹里同时跑多个任务时,结果里会标出其他任务,不会删掉别人的文件。
|
|
147
161
|
|
|
148
162
|
</details>
|
|
149
163
|
|
|
@@ -155,14 +169,16 @@ Codex 和 Claude 轮流往同一个 Harness 对话发消息,每条都标明是
|
|
|
155
169
|
<img src="./docs/benchmarks/token-usage-2026-10/charts/evidence-chain.zh.svg" width="100%" alt="一次真实转交的证据链:用户提需求,Codex 写规格和验收命令,dsh-baton 给文件夹拍快照,DeepSeek Harness 写出 11 个文件,dsh-baton 自己列出改动并跑 npm test,Codex 主动打回一处,dsh-baton 再次验收,Codex 通过,基准测试自己的验收 13/13 通过">
|
|
156
170
|
</p>
|
|
157
171
|
|
|
172
|
+
<p align="center"><picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/zh/divider-dark.svg"><img src="./assets/readme/zh/divider.svg" width="100%" alt=""></picture></p>
|
|
173
|
+
|
|
158
174
|
## 工具
|
|
159
175
|
|
|
160
176
|
<p align="center">
|
|
161
|
-
<img src="./assets/readme/zh/tools.svg" width="100%" alt="工具列表里有 10 个:列出工作区、列出对话、读取对话、列出模型、发送、状态、等待、回答、取消、dsh_call。另外 6 个不常用的经 dsh_call 调用:新建和改名工作区、对话动态、给对话改名、修改排队消息、列出运行">
|
|
177
|
+
<picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/zh/tools-dark.svg"><img src="./assets/readme/zh/tools.svg" width="100%" alt="工具列表里有 10 个:列出工作区、列出对话、读取对话、列出模型、发送、状态、等待、回答、取消、dsh_call。另外 6 个不常用的经 dsh_call 调用:新建和改名工作区、对话动态、给对话改名、修改排队消息、列出运行"></picture>
|
|
162
178
|
</p>
|
|
163
179
|
|
|
164
180
|
<p align="center">
|
|
165
|
-
<img src="./assets/readme/zh/states.
|
|
181
|
+
<picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/zh/states-dark.gif"><img src="./assets/readme/zh/states.gif" width="100%" alt="运行状态:queued、running、waiting、completed、failed、cancelled,Harness 中途重启则为 interrupted。对话正忙时,followup 进排队栏,steer 在下一步插话;不传时跟随 Harness 设置"></picture>
|
|
166
182
|
</p>
|
|
167
183
|
|
|
168
184
|
需要查每个工具的具体参数和返回字段时:
|
|
@@ -181,7 +197,7 @@ Codex 和 Claude 轮流往同一个 Harness 对话发消息,每条都标明是
|
|
|
181
197
|
| `dsh_read_session` | 读某个对话最近的消息和回复(含用到的工具名);已归档的对话会带 `archived: true` |
|
|
182
198
|
| `dsh_send` | 发消息。带 `session_id` 续接那个对话;否则新开对话,建在 `cwd` 或 `workspace_id` 指定的位置,都不带时建在当前对话所在的文件夹(`cwd` 还不是工作区时会先登记;指定的 `cwd` 在当前对话文件夹之外也可以,结果里的 `folder_note` 会提醒)。`checks`:运行结束后 dsh-baton 自己跑的测试命令(见[转交之后怎么验收](#转交之后怎么验收))。立即返回 `run_id`。Harness 里这条消息会标注「由 Claude / ChatGPT 从另一个聊天发送」。已归档的对话会被拒绝:先在 Harness 里取消归档,或新开对话。对话正忙时,`mode` 为 `followup` 会排在当前回合之后,`steer` 会插进正在跑的回合;不传时跟随 Harness 自己的设置(设置 → 繁忙时的发送行为:排队发送或插话发送),读不到设置时按 `followup`。返回里的 `mode_source` 说明用的是哪种。`model` 只在用户点名模型时传(如“DeepSeek-V4 Pro”“v4-pro”;`reasoning_effort` 同理):按 Harness 自己的模型列表匹配,不分大小写,忽略空格、连字符和开头的 DeepSeek,所以 Harness 以后上线的模型(如 V4.1 Pro)一出现在列表里就能用;匹配不到或匹配到多个时,发送直接失败、什么都不创建,并列出可用模型(用 `provider/model` 指定其一)。模型在消息发出前设到该对话上,Harness 的默认模型会恢复原样(Harness 会把对话里选的模型同时存成默认)。不传时,续接的对话沿用它自己的模型,新对话用 Harness 默认模型。返回值的 `model` 和 `model_source` 写明用的是哪个 |
|
|
183
199
|
| `dsh_status` | 查看运行进度:状态、最近的文字和工具调用、最终回复;回合结束但子智能体/后台任务还在跑时给出 `waiting_on`;中途有人在 Harness 界面里发消息时给出 `human_interjections`;被 Harness 重启打断的任务状态为 `interrupted`;以及这次运行发送时用的 `model` |
|
|
184
|
-
| `dsh_wait` |
|
|
200
|
+
| `dsh_wait` | 等运行结束;发消息时带了 `checks` 的,结束后会附上 `evidence`(改了哪些文件、测试结果)(或者等到它停下来问人,见 `dsh_answer`):Codex 每次最多等 3540 秒(它对 dsh-baton 的工具超时减 60 秒;没设时 270 秒),其他客户端 50 秒。没做完会带 `timed_out`,只返回状态,再调用一次即可。能在后台等待的客户端改用 `dsh_send` 返回的 `wait_command`。`dsh_status` 只用来看一眼,不用来等待 |
|
|
185
201
|
| `dsh_answer` | 回答运行中途提出的问题(Harness 的 ask_user_question):每道题可以填选项编号或选项文字、自由填写,或者跳过;可以逐题回答,也可以一次答完。运行一提问,`dsh_wait` 和 `wait_command` 就会立刻返回,并带上题目(`needs_input`、`question`;Harness 那边模型推荐的选项单独放在 `harness_suggested` 里,不再写在选项文字中)。只有你说过让它自己决定时,助手才会按自己的判断回答,这时它会带上 `reason`,并告诉你选了什么、为什么;否则它会把题目转给你,开头先写它自己的建议和理由。你也可以直接在 Harness 窗口里回答,谁先答就算谁的 |
|
|
186
202
|
| `dsh_session_activity` | 经 `dsh_call` 调用。对话此刻在做什么:正在跑的回合、子智能体(任意层级)、后台任务;已归档的对话会带 `archived: true` |
|
|
187
203
|
| `dsh_update_queued` | 经 `dsh_call` 调用。按 `run_id` 修改还在忙碌对话队列里等待的消息:`edit` 改文字,`remove` 撤回,`steer` 立刻插进正在跑的回合。消息一旦进入对话就改不了了 |
|
|
@@ -193,6 +209,8 @@ Codex 和 Claude 轮流往同一个 Harness 对话发消息,每条都标明是
|
|
|
193
209
|
|
|
194
210
|
</details>
|
|
195
211
|
|
|
212
|
+
<p align="center"><picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/zh/divider-dark.svg"><img src="./assets/readme/zh/divider.svg" width="100%" alt=""></picture></p>
|
|
213
|
+
|
|
196
214
|
## 命令行和配置
|
|
197
215
|
|
|
198
216
|
想在终端或脚本里直接驱动 Harness,而不是通过对话时:
|
|
@@ -229,8 +247,7 @@ dsh-baton rename-workspace ~/code/new-app 新名字
|
|
|
229
247
|
| `DSH_BATON_BACKEND` | `auto` | `auto`、`host` 或 `headless` |
|
|
230
248
|
| `DSH_BATON_HOME` | `~/.dsh-baton` | 套接字和 headless 运行记录的位置 |
|
|
231
249
|
| `DSH_BATON_SOCKET` | `$DSH_BATON_HOME/host.sock` | 插件套接字路径(插件和 MCP 两边要一致);Windows 上映射为按用户区分的命名管道,见 [WINDOWS.md](WINDOWS.md) |
|
|
232
|
-
| `DSH_BATON_WAIT_S` | Codex
|
|
233
|
-
| `DSH_BATON_CODEX_HOOK` | `1` | 给 Harness 设为 `0`,插件就不再添加 Codex 的 Stop 钩子 |
|
|
250
|
+
| `DSH_BATON_WAIT_S` | Codex:它对 dsh-baton 的 `tool_timeout_sec` 减 60(插件设的是 3540,没设时 270);其他 `50` | 一次 `dsh_wait` 等多久;要小于客户端的工具超时 |
|
|
234
251
|
| `DSH_BIN` | macOS 应用内的 `dsh`,否则查 `PATH` | headless 模式用的 Harness 命令行 |
|
|
235
252
|
| `DSH_HOME` | `~/.dsh` | Harness 数据目录(headless 模式读取对话用) |
|
|
236
253
|
| `DSH_BATON_ACCOUNT` | `1` | headless 模式下设为 `0` 则改用 API key 路线 |
|
|
@@ -247,6 +264,8 @@ Harness 插件连不上时:
|
|
|
247
264
|
|
|
248
265
|
</details>
|
|
249
266
|
|
|
267
|
+
<p align="center"><picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/zh/divider-dark.svg"><img src="./assets/readme/zh/divider.svg" width="100%" alt=""></picture></p>
|
|
268
|
+
|
|
250
269
|
## 安装细节
|
|
251
270
|
|
|
252
271
|
更新或卸载插件、从 dsh-bridge 升级、从源码运行,或者插件没能注册时:
|
|
@@ -256,13 +275,15 @@ Harness 插件连不上时:
|
|
|
256
275
|
|
|
257
276
|
**插件启用时做了什么**。它把 MCP 服务器复制到 `~/.dsh-baton/app` 这个固定的文件夹,再直接把 MCP 注册写进 `~/.claude.json` 和 `~/.codex/config.toml`,各留一份 `*.bak-dsh-baton` 备份。电脑上有 Node.js ≥ 22.15(在 `PATH` 里能找到)就用它启动服务器;没有的话,就用 Harness 自带的运行环境(Harness 应用本身以 Node 模式运行,`ELECTRON_RUN_AS_NODE=1`),不用另外安装任何东西。两种情况下,只装了桌面应用、`claude` / `codex` 不在 `PATH` 里也能用。每次 Harness 启动都会再检查一遍:已经正确的注册、或者指向另一份可用 dsh-baton 的注册,都不会改动。在 Harness 里输入包名后,安装源会自动切到「npm 官方源」(英文界面是 "Official npm registry"),不用另外选择,也不用重启。不想让插件自动注册,给 Harness 设置 `DSH_BATON_AUTO_REGISTER=0`。
|
|
258
277
|
|
|
259
|
-
**Codex
|
|
278
|
+
**Codex 的工具超时**。Codex 默认 300 秒就会停掉一次 MCP 工具调用,除非服务器那张表里设了 `tool_timeout_sec`。插件会在 `~/.codex/config.toml` 的 `[mcp_servers.dsh-baton]` 里写入 `tool_timeout_sec = 3600`,已有的表没有这一项时也会补上;你自己设过的值会保留。服务器读这个值,每次 `dsh_wait` 等它减 60 秒。Codex 在新开对话时读取这项设置,并且一直沿用:新对话不用重启 Codex 就能用上,已经开着的对话仍然是 Codex 的 300 秒上限。dsh-baton 按对话的开始时间区分(`~/.dsh-baton/codex-timeout.json` 记着这项设置写入的时间),这些对话每次照旧只等 270 秒。
|
|
279
|
+
|
|
280
|
+
**更新到 0.6.4**。不用重启,不用批准,也不用改任何设置。在 Harness 里更新插件后,新的服务器会装到 `~/.dsh-baton/app`,超时设置也会写好;Codex 里正在运行的服务器在下一次调用时就换成新版本(每次 `tools/list` 和 `tools/call` 前都会检查有没有更新的版本)。新对话每次最多等 59 分钟;已经开着的对话照常运行,每次等 270 秒。0.6.0 到 0.6.3 的插件加的 Stop 钩子会连同信任记录自动移除,不用去 Codex 设置里取消勾选。新开的对话,以及 Codex 重启后的所有对话,都完全没有钩子。
|
|
260
281
|
|
|
261
282
|
**更新不用重启**。新版本装进 `~/.dsh-baton/app` 后(插件更新、`setup` 或手动复制),或者同一版本但文件有改动时,Claude Code 和 Codex 里已经开着的对话,下一次调用 `dsh_*` 工具时就会用上:服务器每次调用前检查这个文件夹,启动新版本,并在这次调用的结果里提示一次已经更新。正在进行的 `dsh_wait` 会先在旧版本里跑完。新版本启动失败时,旧版本继续工作,结果里会说明原因。新版本新增的工具,Claude Code 里马上就能用(服务器会通知客户端工具列表变了);Codex 一直用对话开始时的工具列表,新工具要到下一个新对话才会显示;不过旧对话里也能通过 `dsh_call` 马上用上新功能(更新提示里会写明),已有的工具也会立刻用上新代码。
|
|
262
283
|
|
|
263
284
|
**`npx -y dsh-baton-mcp setup`** 在终端里做同样的注册:用于插件没能注册的情况,或者从 MCP 目录过来的用户。插件已经注册过时它什么都不改;插件没装的话,它会提示去添加。
|
|
264
285
|
|
|
265
|
-
**更新**。Harness 只给官方插件提供"更新"按钮,所以要:插件 → dsh-baton-host → **卸载**,再**添加插件** → `dsh-baton-host`。新版本刚发布的一段时间里,Harness 会装上一个版本(pnpm 的 `minimumReleaseAge` 会暂缓刚发布的版本,安装弹窗里会说明);想马上用新版,输入带版本号的名字:`dsh-baton-host@0.6.
|
|
286
|
+
**更新**。Harness 只给官方插件提供"更新"按钮,所以要:插件 → dsh-baton-host → **卸载**,再**添加插件** → `dsh-baton-host`。新版本刚发布的一段时间里,Harness 会装上一个版本(pnpm 的 `minimumReleaseAge` 会暂缓刚发布的版本,安装弹窗里会说明);想马上用新版,输入带版本号的名字:`dsh-baton-host@0.6.4`。预发布版必须写确切版本号添加,比如 `dsh-baton-host@0.6.0-next.0`:Harness 会把 `@next` 解析成一个坏掉的占位包。只输入 `dsh-baton-host` 装的是最新正式版。重新启用后,插件会把 MCP 服务器也更新到同一版本,新开的对话就会用上。万一两边版本对不上,第一次发现不一致的工具调用会提示,并写明哪一边旧、另一边的确切版本号。
|
|
266
287
|
|
|
267
288
|
**卸载**。Harness → 插件 → dsh-baton-host → **卸载**,再运行 `npx -y dsh-baton-mcp setup --remove`。插件分不清"被卸载"和"Harness 退出",所以 MCP 注册交给这条命令删,它也会删掉 `~/.dsh-baton/app`;运行记录留在 `~/.dsh-baton`,不需要的话自己删掉。
|
|
268
289
|
|
|
@@ -296,18 +317,22 @@ codex mcp add dsh-baton -- "$(command -v node)" "$PWD/dsh-baton/src/server.mjs"
|
|
|
296
317
|
|
|
297
318
|
</details>
|
|
298
319
|
|
|
320
|
+
<p align="center"><picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/zh/divider-dark.svg"><img src="./assets/readme/zh/divider.svg" width="100%" alt=""></picture></p>
|
|
321
|
+
|
|
299
322
|
## 安全与限制
|
|
300
323
|
|
|
301
324
|
<p align="center">
|
|
302
|
-
<img src="./assets/readme/zh/security.svg" width="100%" alt="仅当前用户可连(macOS/Linux 用 0600 套接字,Windows 用按用户的命名管道),不开网络端口,沿用 Harness 的沙箱和审批">
|
|
325
|
+
<picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/zh/security-dark.svg"><img src="./assets/readme/zh/security.svg" width="100%" alt="仅当前用户可连(macOS/Linux 用 0600 套接字,Windows 用按用户的命名管道),不开网络端口,沿用 Harness 的沙箱和审批"></picture>
|
|
303
326
|
</p>
|
|
304
327
|
|
|
305
328
|
<p align="center">
|
|
306
|
-
<img src="./assets/readme/zh/limits.svg" width="100%" alt="使用须知:任务进行中在界面里发的话会作为人工插话记到任务上;任务记录在 Harness 重启后还在,被打断的标为 interrupted;Claude Code
|
|
329
|
+
<picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/zh/limits-dark.svg"><img src="./assets/readme/zh/limits.svg" width="100%" alt="使用须知:任务进行中在界面里发的话会作为人工插话记到任务上;任务记录在 Harness 重启后还在,被打断的标为 interrupted;Claude Code 只在运行结束时被唤醒一次,Codex 一次调用最多等 59 分钟"></picture>
|
|
307
330
|
</p>
|
|
308
331
|
|
|
309
332
|
任何能以你的身份运行程序的进程都能通过这个套接字驱动 Harness,这和直接运行 `dsh` 的权限一样。本项目依赖 Harness 0.2.1 系列的内部服务接口,Harness 大版本更新后可能需要跟进。
|
|
310
333
|
|
|
334
|
+
<p align="center"><picture><source media="(prefers-color-scheme: dark)" srcset="./assets/readme/zh/divider-dark.svg"><img src="./assets/readme/zh/divider.svg" width="100%" alt=""></picture></p>
|
|
335
|
+
|
|
311
336
|
## 许可证
|
|
312
337
|
|
|
313
338
|
MIT
|