@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 +65 -0
- package/TROUBLESHOOTING.md +53 -0
- package/package.json +1 -1
- package/plugin.json +1 -1
- package/src/plugin/tools.mjs +1 -1
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.**
|
package/TROUBLESHOOTING.md
CHANGED
|
@@ -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.
|
|
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.
|
|
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": [
|
package/src/plugin/tools.mjs
CHANGED
|
@@ -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.
|
|
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;
|