@twinsearth/w2m-dsh-plugin 1.1.15 → 1.1.17
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 +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +112 -0
- package/README.md +252 -870
- package/codex/mcp-servers.toml +1 -1
- package/docs/PLATFORMS.md +22 -0
- package/package.json +8 -4
- package/plugin.json +1 -1
- package/src/plugin/tools.mjs +119 -5
- package/src/plugin/tools.mjs.bak-c7 +7029 -0
- package/src/relay/fleet-messages.mjs +145 -0
- package/src/relay/message-shards.mjs +124 -0
- package/src/relay/server.mjs +71 -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": "1.1.
|
|
8
|
+
"version": "1.1.17"
|
|
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": "1.1.
|
|
15
|
+
"version": "1.1.17",
|
|
16
16
|
"author": {
|
|
17
17
|
"name": "TwinsEarth"
|
|
18
18
|
},
|
|
@@ -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": "1.1.
|
|
4
|
+
"version": "1.1.17",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "TwinsEarth"
|
|
7
7
|
},
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,118 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project are documented here.
|
|
4
4
|
|
|
5
|
+
## [1.1.17] — 2026-10-18
|
|
6
|
+
|
|
7
|
+
**Fleet chat: messages live in a session, are refused by a byte budget rather than silently dropped, are stored
|
|
8
|
+
encrypted and split across the fleet's own machines, and reach the agent as a tool.**
|
|
9
|
+
|
|
10
|
+
### The store, and the rule it refuses to break
|
|
11
|
+
|
|
12
|
+
`src/relay/fleet-messages.mjs` keeps messages per **session** -- the operator's scope: deleting the session deletes the
|
|
13
|
+
history, and a machine joining or leaving changes who reads the flow, never what was said.
|
|
14
|
+
|
|
15
|
+
The budget is the operator's formula, not a round number:
|
|
16
|
+
|
|
17
|
+
limit = min(200 MB, max(100 MB, used-in-7-days))
|
|
18
|
+
|
|
19
|
+
A message over it is **refused** with the current usage attached (`FLEET_QUOTA_EXCEEDED`); nothing is silently dropped
|
|
20
|
+
and nobody else's words are evicted to make room. Text only: non-strings, control characters and messages over 4 KiB are
|
|
21
|
+
refused by name. Every timestamp comes from the relay's clock, because client clocks in this fleet disagree by tens of
|
|
22
|
+
seconds.
|
|
23
|
+
|
|
24
|
+
### Encrypted sharding with the three rules that keep it from losing data
|
|
25
|
+
|
|
26
|
+
`src/relay/message-shards.mjs` seals a day's messages with AES-256-GCM under a key derived from the fleet key (domain
|
|
27
|
+
separated, no new long-lived secret) and splits the result across the fleet:
|
|
28
|
+
|
|
29
|
+
- **rebuildable** -- the metadata says which machine holds which part, so a reader never guesses;
|
|
30
|
+
- **offline tolerated** -- every part gets **two replicas on two different machines**; one machine being down is the
|
|
31
|
+
normal case;
|
|
32
|
+
- **integrity** -- each shard carries sha256 of its own bytes. A corrupt shard fails as `SHARD_CORRUPT` naming the part
|
|
33
|
+
and machine; a missing one fails as `MISSING_SHARDS` naming **which** parts; a wrong key fails as `AUTH_FAILED`
|
|
34
|
+
without returning partial plaintext.
|
|
35
|
+
|
|
36
|
+
### HTTP and the notification that carries no text
|
|
37
|
+
|
|
38
|
+
`POST /v1/fleet/messages` and `GET /v1/fleet/messages` sit behind the device gate: the author is the token holder, never
|
|
39
|
+
a body field. Every read returns the fleet's current usage so a client can warn before a write is refused.
|
|
40
|
+
`GET /v1/fleet/messages/stream` is SSE and emits **only** `{session_id, message_id, machine_id, at_ms}` -- the text is
|
|
41
|
+
always fetched through the authenticated read, because a broadcast carrying text would send every message to every
|
|
42
|
+
listener and make the membership check decorative.
|
|
43
|
+
|
|
44
|
+
### The twelfth tool: `w2m_chat`
|
|
45
|
+
|
|
46
|
+
`w2m_chat` (`send` / `list`) exposes the above to the agent. It is an ordinary MCP tool available on every transport;
|
|
47
|
+
`w2m_run` remains the only host-only one.
|
|
48
|
+
|
|
49
|
+
### The cost of adding a tool: seven count pins
|
|
50
|
+
|
|
51
|
+
Adding a twelfth tool is not one edit. The count is pinned in **eight** places -- `README` (both languages), four test
|
|
52
|
+
suites (`tools`, `p2p-plugin`, `loader-entry`, `tool-cards`), `scripts/verify-installed.mjs`'s expected list, and
|
|
53
|
+
`test/claims.test.mjs`'s assertion. The first attempt fixed the ones that came to mind and left three red; the gate caught
|
|
54
|
+
each. `docs/PLATFORMS.md` gained a section stating that `w2m_chat` is available over MCP.
|
|
55
|
+
|
|
56
|
+
### Not verified
|
|
57
|
+
|
|
58
|
+
- no client UI panel beyond the generic tool card;
|
|
59
|
+
- the SSE route has module-level notification tests, not a live end-to-end stream assertion;
|
|
60
|
+
- shards are produced and reassembled but **not yet transported** to machines -- that is the relay's next step, and the
|
|
61
|
+
tests say so rather than implying distribution works.
|
|
62
|
+
|
|
63
|
+
### Verified
|
|
64
|
+
|
|
65
|
+
Gate GREEN twice, 15 of 15. tools 120, claims 48, p2p 32, loader 10, fleet-messages 7, message-shards 9, chat-http 3,
|
|
66
|
+
message-notify 3.
|
|
67
|
+
|
|
68
|
+
## [1.1.16] — 2026-10-18
|
|
69
|
+
|
|
70
|
+
**A machine waiting to be admitted now appears where you already answer questions -- and the README leads with how to
|
|
71
|
+
install it.**
|
|
72
|
+
|
|
73
|
+
### Admission in `w2m_approvals`
|
|
74
|
+
|
|
75
|
+
`w2m_approvals` merges `GET /v1/fleet/admission/pending` into its list as `kind:'fleet_admission'` rows, so a machine
|
|
76
|
+
asking to join shows up beside the permission requests already there. Settling an `adm-` id goes to the **relay's**
|
|
77
|
+
decide endpoint, not the local permission index: admission is not an authority escalation, and pushing it through
|
|
78
|
+
`approvalRequestFor` -- whose shape requires a needs-approval verdict and a capability -- would record a lie in the
|
|
79
|
+
audit trail. The list is shared; the stores are not.
|
|
80
|
+
|
|
81
|
+
The countdown is derived from the **relay's clock** (`rabbit_time`), never this machine's: three machines in this fleet
|
|
82
|
+
disagree by tens of seconds, and a local countdown would fire the automatic approval early on a fast machine. The relay
|
|
83
|
+
still owns the decision and still refuses to auto-approve with no member online.
|
|
84
|
+
|
|
85
|
+
### Two defects the tests caught
|
|
86
|
+
|
|
87
|
+
- the merged request omitted `rabbitUrl` and the device token, so it threw into the surrounding catch and the rows were
|
|
88
|
+
**silently missing** -- a probe showed the fetch was never called at all (`calls: []`);
|
|
89
|
+
- the refusal code was read from `json.code`, but protocol errors arrive at `json.error.code`, so `reason_code` was always
|
|
90
|
+
null and a late `ALREADY_DECIDED` decision looked like a success path.
|
|
91
|
+
|
|
92
|
+
Five assertions now cover that seam: rows and their fields, relay-clock countdown, an unreachable relay still showing the
|
|
93
|
+
local queue, `adm-` routing reaching the relay, and a late decision reported rather than thrown.
|
|
94
|
+
|
|
95
|
+
### README rewritten around installation
|
|
96
|
+
|
|
97
|
+
Five routes, easiest first: DSH plugin (zero configuration), npm/MCP for any client, Claude Code marketplace, Codex, and
|
|
98
|
+
the verified release tarball. Then quick start, the 11 tools registered, the `W2M_*` environment a dispatched command
|
|
99
|
+
receives, the fleet model, the security posture, and an explicit **verified / not verified** table that names the approval
|
|
100
|
+
popup, the four-machine `W2M_INDEX` run, the unimplemented chat channel and the macOS P2P downgrade instead of implying
|
|
101
|
+
they work.
|
|
102
|
+
|
|
103
|
+
Two claim checks rejected the first draft and were right: a `SHA256SUMS` release-download URL does not name a
|
|
104
|
+
`<name>-<version>.tgz` asset, and "eleven tools" had to be the measured number.
|
|
105
|
+
|
|
106
|
+
### Not in this release
|
|
107
|
+
|
|
108
|
+
The approval **popup** (a dedicated 10-second countdown control) is not implemented -- the rules are enforced by the
|
|
109
|
+
relay and this tool lists and settles the requests. The fleet chat channel remains designed (FLEET-CHAT-DESIGN.md) and
|
|
110
|
+
not built. No four-machine `W2M_INDEX` run yet.
|
|
111
|
+
|
|
112
|
+
### Verified
|
|
113
|
+
|
|
114
|
+
Gate GREEN (final pass, 15 of 15). 2458 tests in 102 files, 2444 pass, 0 fail, 14 skip. tools 120, tool-cards 8,
|
|
115
|
+
claims 47.
|
|
116
|
+
|
|
5
117
|
## [1.1.15] — 2026-10-17
|
|
6
118
|
|
|
7
119
|
**A machine that cannot join the old way now proves its account, asks to join, and waits for an answer -- and the
|