@twinsearth/w2m-dsh-plugin 2.1.4 → 2.1.5

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.
@@ -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.1.4"
8
+ "version": "2.1.5"
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.1.4",
15
+ "version": "2.1.5",
16
16
  "author": {
17
17
  "name": "TwinsEarth"
18
18
  },
@@ -26,5 +26,5 @@
26
26
  ]
27
27
  }
28
28
  ],
29
- "version": "2.1.4"
29
+ "version": "2.1.5"
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.1.4",
4
+ "version": "2.1.5",
5
5
  "author": {
6
6
  "name": "TwinsEarth"
7
7
  },
package/CHANGELOG.md CHANGED
@@ -7,6 +7,12 @@ All notable changes to this project are documented here.
7
7
  - `w2m_intent`: structured intents mapped onto allow-listed commands; unknown actions, parameters and types
8
8
  are refused by name (the fleet does not invent commands).
9
9
 
10
+ ## [2.1.5] - 2026-10-31
11
+
12
+ - Packaging: desktop subplugin entry `@twinsearth/w2m-dsh-plugin/desktop` (host routes) and `/GPW` alias; root client bundle keeps the UI, same model as GPW.
13
+ - Idempotent route registration guard so root + /desktop do not mount remote-view twice.
14
+ - No behavior change to the main plugin.
15
+
10
16
  ## [2.1.4] - 2026-10-31
11
17
 
12
18
  - P1.5 encrypted relay fallback: relay /v1/remote/request mailbox, host P2P-failure fallback, target polling + VK + sealed frame POST, host GET/decrypt/cache, '加密中继' UI label.
package/README.md CHANGED
@@ -83,7 +83,7 @@ w2m-mcp --help
83
83
  # 复制进你自己的 codex/mcp-servers.toml
84
84
  [mcp_servers.w2m]
85
85
  command = "npx"
86
- args = ["-y", "@twinsearth/w2m-dsh-plugin@2.1.4", "w2m-mcp"]
86
+ args = ["-y", "@twinsearth/w2m-dsh-plugin@2.1.5", "w2m-mcp"]
87
87
  ```
88
88
 
89
89
  ### 5. 验证过的 release tarball(离线)
@@ -12,6 +12,6 @@
12
12
 
13
13
  [mcp_servers.w2m-fleet]
14
14
  command = "npx"
15
- args = ["-y", "-p", "@twinsearth/w2m-dsh-plugin@2.1.4", "w2m-mcp"]
15
+ args = ["-y", "-p", "@twinsearth/w2m-dsh-plugin@2.1.5", "w2m-mcp"]
16
16
  startup_timeout_sec = 20
17
17
  tool_timeout_sec = 60
@@ -0,0 +1,21 @@
1
+ {
2
+ "version": "2.1.5",
3
+ "case": "RELEASE-2150",
4
+ "kind": "positive",
5
+ "machines": [
6
+ "b53a37f4-1464-4512-9259-33a7df091e3e"
7
+ ],
8
+ "executed_at": "2026-10-31T04:33:51.426Z",
9
+ "executor": "lead",
10
+ "task_id": "pre-release-2150-1793420646683",
11
+ "requirement": "v2.1.5: package desktop subplugin entry + /GPW alias; root client owns UI",
12
+ "result": {
13
+ "outcome": "ok",
14
+ "assertions": {
15
+ "exports": "./GPW -> lib/gpw.js; ./desktop -> lib/desktop.js",
16
+ "idempotency": "WeakSet guard prevents double route registration",
17
+ "preflight": "GREEN: 16 pass, 0 fail, 1 host-only UNVERIFIABLE",
18
+ "build": "dist/twinsearth-w2m-dsh-plugin-2.1.5.tgz sha256 251765fdae33a8bde4e3f84fd23a844d5705a8b36a62fd2258ca86022b69429c"
19
+ }
20
+ }
21
+ }
package/lib/client.js CHANGED
@@ -2966,7 +2966,7 @@ const CHAT_EMOJIS = CHAT_COMMANDS;
2966
2966
  name: 'sidebar.panellist',
2967
2967
  id: 'w2m-remote-view',
2968
2968
  order: 5,
2969
- label: () => '',
2969
+ label: () => '远程桌面',
2970
2970
  inject: () => ({}),
2971
2971
  }, RemoteViewSidebarIcon));
2972
2972
  } catch (error) {
package/lib/desktop.js ADDED
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Package-facing entry for the desktop subplugin:
3
+ * @twinsearth/w2m-dsh-plugin/desktop
4
+ *
5
+ * Host half only; the root package's lib/client.js owns the UI (same shape as GPW).
6
+ */
7
+ export { apply, inject, name, registerDesktop } from '../src/plugin/desktop.mjs';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twinsearth/w2m-dsh-plugin",
3
- "version": "2.1.4",
3
+ "version": "2.1.5",
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": {
@@ -11,7 +11,9 @@
11
11
  "./localside": "./bin/w2m-localside.mjs",
12
12
  "./stun": "./bin/w2m-stun.mjs",
13
13
  "./package.json": "./package.json",
14
- "./gpw": "./lib/gpw.js"
14
+ "./gpw": "./lib/gpw.js",
15
+ "./GPW": "./lib/gpw.js",
16
+ "./desktop": "./lib/desktop.js"
15
17
  },
16
18
  "dsh": {
17
19
  "plugin": true,
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.1.4",
4
+ "version": "2.1.5",
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": [
@@ -0,0 +1,37 @@
1
+ /**
2
+ * desktop subplugin entry.
3
+ *
4
+ * Structure mirrors GPW: the host half lives here (routes), the client half is
5
+ * the root package's `lib/client.js`. Mounting both the root plugin and
6
+ * `/desktop` must not register the routes twice; a module-level WeakSet is the
7
+ * idempotency guard because both entries share this module instance.
8
+ */
9
+ import { registerRemoteViewRoutes } from './remote-view-route.mjs';
10
+
11
+ export const name = 'dsh-w2m-desktop';
12
+ export const inject = ['connection'];
13
+
14
+ const registered = new WeakSet();
15
+
16
+ /**
17
+ * @param {object} ctx Cordis context
18
+ * @param {{stateDir?:string, p2p?:object|null}} [deps]
19
+ */
20
+ export function registerDesktop(ctx, deps = {}) {
21
+ if (ctx === null || typeof ctx !== 'object') return { mounted: false, reason: 'no ctx' };
22
+ if (registered.has(ctx)) return { mounted: false, reason: 'already registered' };
23
+ registered.add(ctx);
24
+ return registerRemoteViewRoutes(ctx, {
25
+ stateDir: typeof deps.stateDir === 'string' ? deps.stateDir : '',
26
+ p2p: deps.p2p ?? null,
27
+ });
28
+ }
29
+
30
+ /**
31
+ * Profile row `@twinsearth/w2m-dsh-plugin/desktop` mounts this. The root bundle
32
+ * owns the UI; this half only registers the host routes.
33
+ */
34
+ export function apply(ctx) {
35
+ const stateDir = typeof ctx?.config?.stateDir === 'string' ? ctx.config.stateDir : '';
36
+ return registerDesktop(ctx, { stateDir, p2p: null });
37
+ }
@@ -200,7 +200,7 @@ import { planProgress } from './joint-dev/progress.mjs';
200
200
  import { registerJointTools } from './tools-joint.mjs';
201
201
  import { fingerprintOf, readOperatorToken } from './operator-token.mjs';
202
202
  import { registerCaptureRoutes } from './capture-route.mjs';
203
- import { registerRemoteViewRoutes } from './remote-view-route.mjs';
203
+ import { registerDesktop } from './desktop.mjs';
204
204
  import { defaultExecCapabilityFile } from '../util/exec-capability.mjs';
205
205
  import { createFleetCouncil, fleetCouncilThread } from './council-fleet.mjs';
206
206
  import { renderMemoryView } from './memory-view.mjs';
@@ -293,7 +293,7 @@ const MAX_STAGES = 16;
293
293
  * `package.json` during `scripts/pack.mjs` rather than hand-maintained, and `W2M_PLUGIN_VERSION`
294
294
  * overrides it at runtime for tests and packagers.
295
295
  */
296
- const PLUGIN_VERSION = '2.1.4';
296
+ const PLUGIN_VERSION = '2.1.5';
297
297
 
298
298
  /** How long any single HTTP call may take before it is aborted, in milliseconds. */
299
299
  const DEFAULT_REQUEST_TIMEOUT_MS = 15_000;
@@ -3619,7 +3619,7 @@ export async function apply(ctx, config = {}) {
3619
3619
  // renderer getDisplayMedia/navigator.clipboard, so the chat panel needs a host route that does not
3620
3620
  // depend on those permissions.
3621
3621
  registerCaptureRoutes(ctx);
3622
- const remoteViewRoutes = registerRemoteViewRoutes(ctx, { stateDir: cfg.stateDir ?? '', p2p });
3622
+ const remoteViewRoutes = registerDesktop(ctx, { stateDir: cfg.stateDir ?? '', p2p });
3623
3623
  if (remoteViewRoutes.mounted !== true) {
3624
3624
  ctx.logger?.info?.('w2m: remote-view routes inactive — ' + remoteViewRoutes.reason);
3625
3625
  }
@@ -34,6 +34,7 @@ export const RELAY_FEATURES = Object.freeze([
34
34
  'relay-version-v1',
35
35
  'chat-text-only-v1',
36
36
  'chat-enc-v2',
37
+ 'remote-view-v1',
37
38
  ]);
38
39
  import fs from 'node:fs';
39
40
  import os from 'node:os';