dsh-baton-mcp 0.5.2 → 0.5.3
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/host/package.json +2 -2
- package/package.json +1 -1
- package/server.json +2 -2
- package/src/register.mjs +30 -12
package/host/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-baton-host",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.3",
|
|
4
4
|
"description": "DeepSeek Harness plugin for dsh-baton: adding it is the whole install. Switched on, it registers the dsh-baton MCP server for Claude Code and Codex, then takes the baton over a local, owner-only control socket, runs it in a specific session through the host's own session controller, and hands the result back when the turn is done.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"LICENSE"
|
|
21
21
|
],
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"dsh-baton-mcp": "0.5.
|
|
23
|
+
"dsh-baton-mcp": "0.5.3"
|
|
24
24
|
},
|
|
25
25
|
"license": "MIT",
|
|
26
26
|
"dsh": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-baton-mcp",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.3",
|
|
4
4
|
"mcpName": "io.github.JialaoLiu/dsh-baton",
|
|
5
5
|
"description": "Pass the baton from Claude Code, Codex or any MCP client to a local DeepSeek Harness: an MCP server that hands off tasks, continues a specific session, shows the run live in Harness and hands the result back when it is done.",
|
|
6
6
|
"type": "module",
|
package/server.json
CHANGED
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
"url": "https://github.com/JialaoLiu/dsh-baton",
|
|
8
8
|
"source": "github"
|
|
9
9
|
},
|
|
10
|
-
"version": "0.5.
|
|
10
|
+
"version": "0.5.3",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "npm",
|
|
14
14
|
"identifier": "dsh-baton-mcp",
|
|
15
|
-
"version": "0.5.
|
|
15
|
+
"version": "0.5.3",
|
|
16
16
|
"transport": {
|
|
17
17
|
"type": "stdio"
|
|
18
18
|
}
|
package/src/register.mjs
CHANGED
|
@@ -32,7 +32,8 @@ export function editClaudeConfig(text, entry) {
|
|
|
32
32
|
|
|
33
33
|
export function readClaudeEntry(text) {
|
|
34
34
|
const e = text.trim() ? JSON.parse(text).mcpServers?.[NAME] : null
|
|
35
|
-
|
|
35
|
+
if (!e?.command) return null
|
|
36
|
+
return { command: e.command, args: e.args ?? [], ...(e.env && Object.keys(e.env).length ? { env: e.env } : {}) }
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
const tomlString = (s) => (/['\n\r]/.test(s) ? JSON.stringify(s) : `'${s}'`)
|
|
@@ -61,22 +62,29 @@ export function editCodexConfig(text, entry) {
|
|
|
61
62
|
return out ? out + '\n' : ''
|
|
62
63
|
}
|
|
63
64
|
|
|
64
|
-
// The command and
|
|
65
|
+
// The command, args and env of [mcp_servers.dsh-baton] (and its .env table), as setup
|
|
66
|
+
// writes them (single-line strings).
|
|
65
67
|
export function readCodexEntry(text) {
|
|
66
68
|
const str = String.raw`'[^'\n]*'|"(?:[^"\\\n]|\\.)*"`
|
|
67
69
|
const unquote = (s) => (s.startsWith("'") ? s.slice(1, -1) : JSON.parse(s))
|
|
68
|
-
let
|
|
70
|
+
let table = null
|
|
69
71
|
let command = null, args = []
|
|
72
|
+
const env = {}
|
|
70
73
|
for (const line of text.split(/\r?\n/)) {
|
|
71
|
-
if (ANY_TABLE.test(line))
|
|
72
|
-
|
|
74
|
+
if (ANY_TABLE.test(line)) {
|
|
75
|
+
const m = line.match(/^\s*\[\s*mcp_servers\s*\.\s*(["']?)dsh-baton\1\s*(\.\s*env\s*)?\]/)
|
|
76
|
+
table = m ? (m[2] ? 'env' : 'main') : null
|
|
77
|
+
} else if (table === 'main') {
|
|
73
78
|
const c = line.match(new RegExp(`^\\s*command\\s*=\\s*(${str})`))
|
|
74
79
|
if (c) command = unquote(c[1])
|
|
75
80
|
const a = line.match(/^\s*args\s*=\s*\[(.*)\]/)
|
|
76
81
|
if (a) args = [...a[1].matchAll(new RegExp(str, 'g'))].map((m) => unquote(m[0]))
|
|
82
|
+
} else if (table === 'env') {
|
|
83
|
+
const kv = line.match(new RegExp(`^\\s*([\\w-]+)\\s*=\\s*(${str})`))
|
|
84
|
+
if (kv) env[kv[1]] = unquote(kv[2])
|
|
77
85
|
}
|
|
78
86
|
}
|
|
79
|
-
return command ? { command, args } : null
|
|
87
|
+
return command ? { command, args, ...(Object.keys(env).length ? { env } : {}) } : null
|
|
80
88
|
}
|
|
81
89
|
|
|
82
90
|
// Write only when the content changes, keep one backup, and replace the file atomically.
|
|
@@ -124,10 +132,10 @@ export function nodeVersionOk(version) {
|
|
|
124
132
|
return major > MIN_NODE[0] || (major === MIN_NODE[0] && minor >= MIN_NODE[1])
|
|
125
133
|
}
|
|
126
134
|
|
|
127
|
-
//
|
|
128
|
-
//
|
|
129
|
-
//
|
|
130
|
-
//
|
|
135
|
+
// The user's own Node.js for the MCP server, preferred over Harness's runtime (see
|
|
136
|
+
// harnessRuntime): the first `node` on PATH, then the usual install folders, never the
|
|
137
|
+
// launcher scripts inside the Harness app (they only work from Harness itself), and only
|
|
138
|
+
// a new enough one.
|
|
131
139
|
export function findNode({ env = process.env, platform = process.platform, exclude = [], version = nodeVersion } = {}) {
|
|
132
140
|
const exe = platform === 'win32' ? 'node.exe' : 'node'
|
|
133
141
|
const p = platform === 'win32' ? path.win32 : path.posix
|
|
@@ -212,7 +220,17 @@ export function autoRegister({ root, home = os.homedir(), env = process.env, nod
|
|
|
212
220
|
serverRoot = app
|
|
213
221
|
}
|
|
214
222
|
const script = path.join(serverRoot, 'src', 'server.mjs')
|
|
215
|
-
|
|
223
|
+
// Whether an entry can start a server. A bare command (`npx -y dsh-baton-mcp`, as MCP
|
|
224
|
+
// directories suggest) is the user's own choice and resolved on the client's PATH: kept.
|
|
225
|
+
// Harness's own binary only works in Node mode.
|
|
226
|
+
const bare = (cmd) => !/[\\/]/.test(cmd)
|
|
227
|
+
const works = (e) => {
|
|
228
|
+
if (!e?.command) return false
|
|
229
|
+
// `node /old/path/server.mjs` with that file gone is still broken.
|
|
230
|
+
if (bare(e.command)) return !e.args?.[0] || bare(e.args[0]) || fs.existsSync(e.args[0])
|
|
231
|
+
if (!fs.existsSync(e.command) || !e.args?.[0] || !fs.existsSync(e.args[0])) return false
|
|
232
|
+
return !fallback || path.resolve(e.command) !== path.resolve(fallback.command) || e.env?.ELECTRON_RUN_AS_NODE === '1'
|
|
233
|
+
}
|
|
216
234
|
const list = clients(env, home)
|
|
217
235
|
let launch = node ? { command: node } : null
|
|
218
236
|
for (const c of list) {
|
|
@@ -221,7 +239,7 @@ export function autoRegister({ root, home = os.homedir(), env = process.env, nod
|
|
|
221
239
|
const text = fs.existsSync(c.file) ? fs.readFileSync(c.file, 'utf8') : ''
|
|
222
240
|
const current = c.read(text)
|
|
223
241
|
if (works(current)) {
|
|
224
|
-
const same = path.resolve(current.args[0]) === path.resolve(script)
|
|
242
|
+
const same = !bare(current.command) && path.resolve(current.args[0]) === path.resolve(script)
|
|
225
243
|
result.clients.push({ id: c.id, label: c.label, state: same ? 'unchanged' : 'kept', script: current.args[0] })
|
|
226
244
|
continue
|
|
227
245
|
}
|