@twinsearth/w2m-dsh-plugin 2.1.4 → 2.1.6

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.6"
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.6",
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.6"
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.6",
5
5
  "author": {
6
6
  "name": "TwinsEarth"
7
7
  },
package/CHANGELOG.md CHANGED
@@ -7,6 +7,18 @@ 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.6] - 2026-10-31
11
+
12
+ - Desktop subplugin activation fix: no longer requires a Cordis `config` service; stateDir resolves from W2M_STATE_DIR / DSH_HOME / ~/.dsh/xclient.
13
+ - Plugin details now lists three components: root, /desktop, /gpw; /desktop activates alongside the root bundle (idempotent route guard).
14
+ - Removed the duplicate case-only `./GPW` export key that broke case-insensitive manifest tooling; lowercase `/gpw` remains.
15
+
16
+ ## [2.1.5] - 2026-10-31
17
+
18
+ - Packaging: desktop subplugin entry `@twinsearth/w2m-dsh-plugin/desktop` (host routes) and `/GPW` alias; root client bundle keeps the UI, same model as GPW.
19
+ - Idempotent route registration guard so root + /desktop do not mount remote-view twice.
20
+ - No behavior change to the main plugin.
21
+
10
22
  ## [2.1.4] - 2026-10-31
11
23
 
12
24
  - 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.6", "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.6", "w2m-mcp"]
16
16
  startup_timeout_sec = 20
17
17
  tool_timeout_sec = 60
package/cordis.patch.yml CHANGED
@@ -127,6 +127,10 @@
127
127
  #
128
128
  # What it does once enabled: answers `approval/request` with at most 10 auto-approvals per rolling 60 s, at
129
129
  # least 3000 ms apart, and defers everything past that to the human prompt, where it waits.
130
+ - id: dsh-desktop
131
+ name: '@twinsearth/w2m-dsh-plugin/desktop'
132
+ disabled: true
133
+ config: {}
130
134
  - id: dsh-gpw
131
135
  name: '@twinsearth/w2m-dsh-plugin/gpw'
132
136
  disabled: true
@@ -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
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "version": "2.1.6",
3
+ "case": "RELEASE-2160",
4
+ "kind": "positive",
5
+ "machines": [
6
+ "b53a37f4-1464-4512-9259-33a7df091e3e"
7
+ ],
8
+ "executed_at": "2026-10-31T05:42:29.214Z",
9
+ "executor": "lead",
10
+ "task_id": "pre-release-2160-1793424835992",
11
+ "requirement": "v2.1.6: desktop subplugin activates without config service; three components listed",
12
+ "result": {
13
+ "outcome": "ok",
14
+ "assertions": {
15
+ "desktop": "inject=[connection]; stateDir fallback",
16
+ "components": "root + /desktop + /gpw",
17
+ "preflight": "GREEN: 16 pass, 0 fail, 1 host-only UNVERIFIABLE",
18
+ "build": "dist/twinsearth-w2m-dsh-plugin-2.1.6.tgz sha256 1588fd7f55aca6401367360b75599827c154005c545bc4ff13432490e4a3674a"
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.6",
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,8 @@
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
+ "./desktop": "./lib/desktop.js"
15
16
  },
16
17
  "dsh": {
17
18
  "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.6",
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,40 @@
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
+ import { homedir } from 'node:os';
11
+ import { join } from 'node:path';
12
+
13
+ export const name = 'dsh-w2m-desktop';
14
+ export const inject = ['connection'];
15
+
16
+ const registered = new WeakSet();
17
+
18
+ /**
19
+ * @param {object} ctx Cordis context
20
+ * @param {{stateDir?:string, p2p?:object|null}} [deps]
21
+ */
22
+ export function registerDesktop(ctx, deps = {}) {
23
+ if (ctx === null || typeof ctx !== 'object') return { mounted: false, reason: 'no ctx' };
24
+ if (registered.has(ctx)) return { mounted: false, reason: 'already registered' };
25
+ registered.add(ctx);
26
+ return registerRemoteViewRoutes(ctx, {
27
+ stateDir: typeof deps.stateDir === 'string' ? deps.stateDir : '',
28
+ p2p: deps.p2p ?? null,
29
+ });
30
+ }
31
+
32
+ /**
33
+ * Profile row `@twinsearth/w2m-dsh-plugin/desktop` mounts this. The root bundle
34
+ * owns the UI; this half only registers the host routes.
35
+ */
36
+ export function apply(ctx) {
37
+ const stateDir = process.env.W2M_STATE_DIR
38
+ ?? (process.env.DSH_HOME ? join(process.env.DSH_HOME, 'xclient') : join(homedir(), '.dsh', 'xclient'));
39
+ return registerDesktop(ctx, { stateDir, p2p: null });
40
+ }
@@ -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.6';
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';