@twinsearth/w2m-dsh-plugin 0.59.0 → 0.60.0

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/CHANGELOG.md CHANGED
@@ -4,6 +4,71 @@ All notable changes to this project are documented here. The format follows
4
4
  [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
5
5
  adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.60.0] — 2026-10-16
8
+
9
+ **Two things learned from a client that would not start, neither of which was a crash in this plugin.**
10
+
11
+ ### §3.1 in `TROUBLESHOOTING.md`: check the lock before you check the plugin
12
+
13
+ A launch that leaves **no process at all** is a different failure from one that starts and reports something, and
14
+ the existing §3 procedure will mislead anyone who skips that distinction — it assumes the application *ran*.
15
+
16
+ **The mechanism is one function in `@deepseek-ai/dsh-desktop`'s `lib/main.js`:**
17
+
18
+ ```js
19
+ function claimDesktopSingleInstance(application, focusOwner) {
20
+ if (!application.requestSingleInstanceLock()) {
21
+ application.quit(); // no dialog, no error, no window
22
+ return false;
23
+ }
24
+ ```
25
+
26
+ **A second launch is silently discarded while the first instance holds the lock.** Electron registers it against
27
+ the *application*, not a directory — which is why the two natural remedies both fail, and why the section now says
28
+ so before offering any plugin diagnosis:
29
+
30
+ | What was tried | Why it did nothing |
31
+ |---|---|
32
+ | disable third-party plugins before restarting | the new process quits at the lock, before plugin loading |
33
+ | reinstall the client (new folder, new exe) | a new directory does not release an application-scoped lock |
34
+
35
+ **Deleting `~/.dsh` fixed it — not because anything in it was corrupt, but because the deletion took down the
36
+ process still holding the lock.** The section now leads with the measurement that costs nothing:
37
+
38
+ ```powershell
39
+ Get-Process -Name 'DeepSeek Harness' | Select-Object Id, StartTime
40
+ ```
41
+
42
+ **Processes listed → it is the lock, end them and retry. Nothing listed → the failure really is pre-lock, and §3's
43
+ procedure applies.** The deleted directory carried session history and profile configuration; **`Stop-Process`
44
+ would have cost nothing.**
45
+
46
+ ### `scripts/session-retention.mjs`: the store is bounded, out-of-band, as DSH says it must be
47
+
48
+ `@deepseek-ai/dsh-session-persistence`'s README, under *Known Limitations*:
49
+
50
+ > **No deletion or retention API** — pruning stored sessions is **out-of-band backend maintenance**.
51
+
52
+ **So this is not a workaround for a missing feature: the host states retention is the operator's job.** The
53
+ measurement that motivated it is that **one session reached 18.03 MiB of an 18.07 MiB store**, nothing bounds it,
54
+ and every start reads the store.
55
+
56
+ Three refusals are built in, and each is a deliberate limit rather than an omission:
57
+
58
+ * **The newest session of every workspace is never removed.** DSH writes to it, and *which* process is writing
59
+ cannot be checked reliably from outside — so the rule is the one that needs no knowledge of the running
60
+ process.
61
+ * **`--apply` is required.** The default prints the plan and exits 0. **A tool that removes conversation history
62
+ shows what it will remove before it removes it.**
63
+ * **A directory that is not a session is reported, not touched**, because the layout is read from the filesystem
64
+ rather than assumed.
65
+
66
+ **Verified against the real store:** at a 256 MiB cap it reports *"under the cap — nothing to remove"*; at a
67
+ 1 MiB cap it plans two removals and leaves the 18 MiB live session alone.
68
+
69
+ **No test count change** — both additions are a document and a script, and the script is exercised by hand against
70
+ the store it bounds rather than by a fixture that would not resemble it.
71
+
7
72
  ## [0.59.0] — 2026-10-16
8
73
 
9
74
  **Every published bin can now be imported without killing the importing process — measured, not reasoned about.**
@@ -258,6 +258,59 @@ after removal, remove the `w2m` row from `cordis.patch.yml` by hand (§2) before
258
258
  **Not us.** If the failure is in a _different_ plugin's entry and this one is merely in the same
259
259
  profile, the loader reports the package name in the same line — read it before assuming it is ours.
260
260
 
261
+ ### 3.1 First rule: if a double-click produces NO process, it is not a plugin
262
+
263
+ **This section's decision procedure below will mislead you if you skip this step.** It assumes the
264
+ application *ran and reported something*. A launch that leaves **no process at all** — nothing in Task
265
+ Manager, no window, no dialog — is a different failure, and the plugin is not the cause.
266
+
267
+ **The mechanism**, read out of `@deepseek-ai/dsh-desktop`'s `lib/main.js`:
268
+
269
+ ```js
270
+ function claimDesktopSingleInstance(application, focusOwner) {
271
+ if (!application.requestSingleInstanceLock()) {
272
+ application.quit(); // no dialog, no error, no window
273
+ return false;
274
+ }
275
+ application.on("second-instance", focusOwner);
276
+ return true;
277
+ }
278
+ ```
279
+
280
+ **A second launch is silently discarded while the first instance holds the lock.** Electron registers that
281
+ lock against the *application*, not against a directory, which is why the two most natural remedies both
282
+ fail:
283
+
284
+ | What you try | Why it does nothing |
285
+ |---|---|
286
+ | **Disable third-party plugins before restarting** | The new process never reaches plugin loading — it quits at the lock |
287
+ | **Reinstall the client (new folder, new exe)** | A new directory does not release a lock registered against the application |
288
+
289
+ **Check the lock before touching anything else:**
290
+
291
+ ```powershell
292
+ # Windows
293
+ Get-Process -Name 'DeepSeek Harness' | Select-Object Id, StartTime
294
+ ```
295
+
296
+ ```bash
297
+ # macOS / Linux
298
+ pgrep -fl "DeepSeek Harness"
299
+ ```
300
+
301
+ * **Processes listed** → it is the lock, and the app is not broken. **End them and start again.** On
302
+ Windows: `Stop-Process -Name 'DeepSeek Harness' -Force`. Do **not** delete `~/.dsh`.
303
+ * **Nothing listed** → the failure really is before the lock, and *then* §3's procedure below applies.
304
+
305
+ **A measured case, so the cost is on record.** A restart after upgrading to **v0.58.0** produced no
306
+ process. Disabling third-party plugins and reinstalling the client both changed nothing; **deleting the
307
+ entire `~/.dsh` directory fixed it** — not because anything in that directory was corrupt, but because
308
+ **the deletion took down the process still holding the lock**, and the next launch then became the first
309
+ instance. **Killing that process is the smaller, safer step, and it is the one to try first.**
310
+
311
+ **What this cost, stated plainly:** the deleted directory carried session history and profile
312
+ configuration that no longer exists. **`Stop-Process` would have cost nothing.**
313
+
261
314
  ---
262
315
 
263
316
  ## 4. A machine is listed but never answers
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twinsearth/w2m-dsh-plugin",
3
- "version": "0.59.0",
3
+ "version": "0.60.0",
4
4
  "description": "DSH: Windows2MacOS — drive the same project on online Windows and macOS machines from one DeepSeek account, across networks and regions. P2P hole punching is the default path (relay + shared server as rendezvous, ledger and fallback), with a bundled STUN responder, Tailscale/public-VPS/tunnel shapes, Rabbit relay + per-machine Localside + eight DSH tools (replicate / split), nine aggregate verdicts and signed requests.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
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": "0.59.0",
4
+ "version": "0.60.0",
5
5
  "description": "Cross-platform fleet execution between Windows and macOS: one DeepSeek Harness account, a Rabbit relay, and signed device identity. Ships four Agent Skills describing fleet dispatch, field-level memory acceptance, session references, and resource scheduling.",
6
6
  "license": "MIT",
7
7
  "keywords": [
@@ -208,7 +208,7 @@ const MAX_STAGES = 16;
208
208
  * `package.json` during `scripts/pack.mjs` rather than hand-maintained, and `W2M_PLUGIN_VERSION`
209
209
  * overrides it at runtime for tests and packagers.
210
210
  */
211
- const PLUGIN_VERSION = '0.59.0';
211
+ const PLUGIN_VERSION = '0.60.0';
212
212
 
213
213
  /** How long any single HTTP call may take before it is aborted, in milliseconds. */
214
214
  const DEFAULT_REQUEST_TIMEOUT_MS = 15_000;