@twinsearth/w2m-dsh-plugin 2.2.1 → 2.2.2
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/.claude-plugin/marketplace.json +3 -3
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +12 -2
- package/README.md +1 -1
- package/codex/mcp-servers.toml +1 -1
- package/docs/acceptance/2.2.2/RELEASE-2220.json +25 -0
- package/lib/client.js +36 -4
- package/package.json +1 -1
- package/plugin.json +1 -1
- package/src/plugin/tools.mjs +1 -1
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
},
|
|
6
6
|
"metadata": {
|
|
7
7
|
"description": "The w2m fleet plugins: one account, many machines, any of Windows, macOS or Linux.",
|
|
8
|
-
"version": "2.2.
|
|
8
|
+
"version": "2.2.2"
|
|
9
9
|
},
|
|
10
10
|
"plugins": [
|
|
11
11
|
{
|
|
12
12
|
"name": "w2m-fleet",
|
|
13
13
|
"source": "./",
|
|
14
14
|
"description": "Read fleet state and dispatch commands across the machines registered to one account. Read-only MCP surface: the five exposed tools cannot change anything.",
|
|
15
|
-
"version": "2.2.
|
|
15
|
+
"version": "2.2.2",
|
|
16
16
|
"author": {
|
|
17
17
|
"name": "TwinsEarth"
|
|
18
18
|
},
|
|
@@ -26,5 +26,5 @@
|
|
|
26
26
|
]
|
|
27
27
|
}
|
|
28
28
|
],
|
|
29
|
-
"version": "2.2.
|
|
29
|
+
"version": "2.2.2"
|
|
30
30
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "w2m-fleet",
|
|
3
3
|
"description": "Drive the same project on online Windows, macOS and Linux machines from one account: read fleet state, dispatch commands and read results. The MCP surface is deliberately read-only.",
|
|
4
|
-
"version": "2.2.
|
|
4
|
+
"version": "2.2.2",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "TwinsEarth"
|
|
7
7
|
},
|
package/CHANGELOG.md
CHANGED
|
@@ -5,8 +5,18 @@ All notable changes to this project are documented here.
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
7
|
- `w2m_intent`: structured intents mapped onto allow-listed commands; unknown actions, parameters and types
|
|
8
|
-
are refused by name (the fleet does not invent commands).
|
|
9
|
-
|
|
8
|
+
are refused by name (the fleet does not invent commands).
|
|
9
|
+
|
|
10
|
+
## [2.2.2] - 2026-11-05
|
|
11
|
+
|
|
12
|
+
- DSH 0.2.2-rc.1 compatibility: composer popups (the dispatch-target menu and the Node-execution menu)
|
|
13
|
+
now render through a `react-dom` portal under `document.body`. The release candidate puts
|
|
14
|
+
`container-type: inline-size` on the composer row, which makes that row the containing block for
|
|
15
|
+
`position: fixed` descendants; the Node-execution menu was positioned relative to the row and its
|
|
16
|
+
options could not be selected. A portal keeps the viewport coordinates the menus compute.
|
|
17
|
+
- Loader tests: the bundle-fetch helper sends a Fetch `Request` as 0.2.2-rc.1 requires, the real-page
|
|
18
|
+
probe seeds a Workspace, opens the Node-execution menu and selects temporary execution, and the
|
|
19
|
+
host route probe confirms `GET/POST /api/w2m/capability` is mounted.
|
|
10
20
|
## [2.2.1] - 2026-11-01
|
|
11
21
|
|
|
12
22
|
- Fleet identity is now per-account **home**-first. Each machine records the fleet key it actually joined under `fleet-home.json` beside `device.json`; switching back to an account returns to that account’s previous fleet instead of deriving a new one. This is the “whoever leaves returns by themselves” rule: a first appearance of account B may join B’s account fleet, but an existing home for A is never rewritten by B, and no other machine is moved.
|
package/README.md
CHANGED
|
@@ -92,7 +92,7 @@ w2m-mcp --help
|
|
|
92
92
|
# 复制进你自己的 codex/mcp-servers.toml
|
|
93
93
|
[mcp_servers.w2m]
|
|
94
94
|
command = "npx"
|
|
95
|
-
args = ["-y", "@twinsearth/w2m-dsh-plugin@2.2.
|
|
95
|
+
args = ["-y", "@twinsearth/w2m-dsh-plugin@2.2.2", "w2m-mcp"]
|
|
96
96
|
```
|
|
97
97
|
|
|
98
98
|
### 5. 验证过的 release tarball(离线)
|
package/codex/mcp-servers.toml
CHANGED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "2.2.2",
|
|
3
|
+
"case": "RELEASE-2220",
|
|
4
|
+
"kind": "positive",
|
|
5
|
+
"machines": [
|
|
6
|
+
"b53a37f4-1464-4512-9259-33a7df091e3e"
|
|
7
|
+
],
|
|
8
|
+
"executed_at": "2026-11-04T20:16:04.717Z",
|
|
9
|
+
"executor": "lead",
|
|
10
|
+
"task_id": "pre-release-2220-1793823364724",
|
|
11
|
+
"requirement": "v2.2.2: DSH 0.2.2-rc.1 users can open the Node-execution menu and select temporary execution from the composer",
|
|
12
|
+
"commands": [
|
|
13
|
+
["node", "--test", "--test-force-exit", "test/client-bundle.test.mjs"],
|
|
14
|
+
["node", "--test", "--test-force-exit", "test/loader-entry.test.mjs"]
|
|
15
|
+
],
|
|
16
|
+
"result": {
|
|
17
|
+
"outcome": "ok",
|
|
18
|
+
"assertions": {
|
|
19
|
+
"client": "test/client-bundle.test.mjs 36/36: popup menus portal to document.body when react-dom is available and fall back inline without it",
|
|
20
|
+
"loader": "test/loader-entry.test.mjs 10/10 against the packed 2.2.2 tarball in the real DSH 0.2.2-rc.1 Loader and its own Edge page; the route probe finds /api/w2m/capability and W2M_CAPABILITY_PROBE=1 opens the Node-execution menu and selects temporary execution",
|
|
21
|
+
"dsh": "the installed runtime is @deepseek-ai/dsh-desktop-runtime 0.2.2-rc.1 (resources/app.asar), not the 0.2.1-rc.5 profile pins",
|
|
22
|
+
"scope": "local code and packed artifact only; no installed profile was edited by the tests; the release is published separately"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
package/lib/client.js
CHANGED
|
@@ -66,6 +66,37 @@ window.__ModuleLoader__.load({
|
|
|
66
66
|
|
|
67
67
|
const React = require('react');
|
|
68
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Render a popup under `document.body`.
|
|
71
|
+
*
|
|
72
|
+
* DSH 0.2.2-rc.1 puts `container-type: inline-size` on the composer row. Layout containment makes
|
|
73
|
+
* that row the containing block for `position: fixed` descendants, so a menu rendered inside the
|
|
74
|
+
* composer slot is positioned relative to the row (and can be clipped) instead of the viewport.
|
|
75
|
+
* A portal keeps the viewport coordinates the menus already compute. `react-dom` is a platform
|
|
76
|
+
* seed in the Web shell; the lazy require keeps this bundle loadable where only React is present,
|
|
77
|
+
* and the inline fallback preserves the old behavior if the portal cannot be created.
|
|
78
|
+
*
|
|
79
|
+
* @param {object|null} node - menu element.
|
|
80
|
+
* @returns {object|null} portal element, or the original node.
|
|
81
|
+
*/
|
|
82
|
+
let portalRuntime;
|
|
83
|
+
let portalUnavailable = false;
|
|
84
|
+
function portalNode(node) {
|
|
85
|
+
if (node === null || portalUnavailable) return node;
|
|
86
|
+
if (typeof document === 'undefined' || document.body === null || document.body === undefined) return node;
|
|
87
|
+
try {
|
|
88
|
+
if (portalRuntime === undefined) portalRuntime = require('react-dom');
|
|
89
|
+
if (typeof portalRuntime?.createPortal !== 'function') {
|
|
90
|
+
portalUnavailable = true;
|
|
91
|
+
return node;
|
|
92
|
+
}
|
|
93
|
+
return portalRuntime.createPortal(node, document.body);
|
|
94
|
+
} catch {
|
|
95
|
+
portalUnavailable = true;
|
|
96
|
+
return node;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
69
100
|
// -------------------------------------------------------------------------------------------
|
|
70
101
|
// Wire
|
|
71
102
|
// -------------------------------------------------------------------------------------------
|
|
@@ -2285,7 +2316,7 @@ function UpdateSettingsSection() {
|
|
|
2285
2316
|
};
|
|
2286
2317
|
|
|
2287
2318
|
const menu = open && placement !== null
|
|
2288
|
-
? h('div', {
|
|
2319
|
+
? portalNode(h('div', {
|
|
2289
2320
|
className: cls('menu'),
|
|
2290
2321
|
role: 'listbox',
|
|
2291
2322
|
'aria-label': t('targetLabel', { name: label }),
|
|
@@ -2381,7 +2412,7 @@ function UpdateSettingsSection() {
|
|
|
2381
2412
|
? h('div', { key: 'hint', className: cls('relayHint') }, t('relayFold', { count: relayFold.hidden_count }))
|
|
2382
2413
|
: null,
|
|
2383
2414
|
]),
|
|
2384
|
-
])
|
|
2415
|
+
]))
|
|
2385
2416
|
: null;
|
|
2386
2417
|
|
|
2387
2418
|
return h(React.Fragment, null, [
|
|
@@ -3106,7 +3137,7 @@ const CHAT_EMOJIS = CHAT_COMMANDS;
|
|
|
3106
3137
|
};
|
|
3107
3138
|
|
|
3108
3139
|
const menu = open && placement !== null
|
|
3109
|
-
? h('div', {
|
|
3140
|
+
? portalNode(h('div', {
|
|
3110
3141
|
className: 'w2mCap_menu',
|
|
3111
3142
|
role: 'menu',
|
|
3112
3143
|
'aria-label': t('capMenuLabel'),
|
|
@@ -3118,7 +3149,7 @@ const CHAT_EMOJIS = CHAT_COMMANDS;
|
|
|
3118
3149
|
h('button', { key: 'temp', type: 'button', className: 'w2mCap_option', 'data-active': capability?.state === 'temporary' ? 'true' : 'false', onClick: () => choose('temporary', 24 * 60 * 60 * 1000) }, t('capTemporary')),
|
|
3119
3150
|
h('button', { key: 'perm', type: 'button', className: 'w2mCap_option', 'data-active': capability?.state === 'permanent' ? 'true' : 'false', onClick: () => choose('permanent') }, t('capPermanent')),
|
|
3120
3151
|
error === null ? null : h('div', { key: 'err', className: 'w2mCap_note', role: 'status' }, error),
|
|
3121
|
-
])
|
|
3152
|
+
]))
|
|
3122
3153
|
: null;
|
|
3123
3154
|
|
|
3124
3155
|
return h(React.Fragment, null, [
|
|
@@ -3449,6 +3480,7 @@ const CHAT_EMOJIS = CHAT_COMMANDS;
|
|
|
3449
3480
|
exports.FleetChat = FleetChat;
|
|
3450
3481
|
exports.injectStyle = injectStyle;
|
|
3451
3482
|
exports.makeTranslator = makeTranslator;
|
|
3483
|
+
exports.portalNode = portalNode;
|
|
3452
3484
|
return module.exports;
|
|
3453
3485
|
},
|
|
3454
3486
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@twinsearth/w2m-dsh-plugin",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.2",
|
|
4
4
|
"description": "Run one project across your own Windows and macOS machines from a single DeepSeek account, through 11 w2m_* tools. Four coordination modes (replicate, split, broadcast, pipeline) and six aggregate verdicts (consistent, divergent, divergent-platform, failed, partial, unverifiable). P2P hole punching by default, with a bundled relay, STUN responder and ledger fallback, so the fleet needs no third-party service. Joining needs a pairing code plus autoStartAgent: true; installing alone does not join.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
package/plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
|
|
3
3
|
"name": "twinsearth-w2m-dsh",
|
|
4
|
-
"version": "2.2.
|
|
4
|
+
"version": "2.2.2",
|
|
5
5
|
"description": "Run one project across your own Windows and macOS machines from a single DeepSeek account, through 12 w2m_* tools. Four coordination modes (replicate, split, broadcast, pipeline) and six aggregate verdicts (consistent, divergent, divergent-platform, failed, partial, unverifiable). P2P hole punching by default, with a bundled relay, STUN responder and ledger fallback, so the fleet needs no third-party service. Joining needs a pairing code plus autoStartAgent: true; installing alone does not join.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"keywords": [
|
package/src/plugin/tools.mjs
CHANGED
|
@@ -296,7 +296,7 @@ const MAX_STAGES = 16;
|
|
|
296
296
|
* `package.json` during `scripts/pack.mjs` rather than hand-maintained, and `W2M_PLUGIN_VERSION`
|
|
297
297
|
* overrides it at runtime for tests and packagers.
|
|
298
298
|
*/
|
|
299
|
-
const PLUGIN_VERSION = '2.2.
|
|
299
|
+
const PLUGIN_VERSION = '2.2.2';
|
|
300
300
|
|
|
301
301
|
/** How long any single HTTP call may take before it is aborted, in milliseconds. */
|
|
302
302
|
const DEFAULT_REQUEST_TIMEOUT_MS = 15_000;
|